Android平台和java平台 DES加密解密互通程序及其不能互通的原因 .

网上的demo一搜一大堆,但是,基本上都是一知半解(包括我)。为什么呢?我在尝试分别在两个平台加密的时候,竟然发现Android DES 加密和java DES加密的程序不能互通。就是加密的结果不一样,更不要说Android平台的加密输入作为java DES的解密输出了。这样的话,客户端和服务器端就不能进行通信了。我网上之前也发帖子问了不少人,但是回答都不满意。

今天部门的另外一个同事跟我说了一下,才解决了这个不能互通的问题。

调用DES加密算法包最精要的就是下面两句话:

Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);

CBC是工作模式,DES一共有电子密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输出反馈模式(OFB)四种模式,

PKCS5Padding是填充模式,还有其它的填充模式:

然后,cipher.init()一共有三个参数:Cipher.ENCRYPT_MODE, key, zeroIv,zeroIv就是初始化向量,一个8为字符数组。

工作模式、填充模式、初始化向量这三种因素一个都不能少。否则,如果你不指定的话,那么就要程序就要调用默认实现。问题就来了,这就与平台有关了。难怪网上一搜"DES加密结果不一致“,出现n多网页结果。(之前我并没有指定IV,被折磨了2周)

源程序如下(从java平台到android平台,我根本没有更改一行代码):

另外,一般情况下,加密后的结果都会用base64编码进行传输。

java平台:

主程序

01 public class testDES {
02  
03     /**
04      * @param args
05      * @throws Exception
06      */
07     public static void main(String[] args) throws Exception {
08         // TODO Auto-generated method stub
09         String key = "12345678";
10         String text = "12345678";
11         String result1 = DES.encryptDES(text,key);
12         String result2 = DES.decryptDES(result1, key);
13         System.out.println(result1);
14         System.out.println(result2);
15     }
16 }

用到的DES加密类
01 import javax.crypto.Cipher;
02 import javax.crypto.spec.IvParameterSpec;
03 import javax.crypto.spec.SecretKeySpec;
04  
05 public class DES {
06     private static byte[] iv = {1,2,3,4,5,6,7,8};
07     public static String encryptDES(String encryptString, String encryptKey)throws Exception {
08 //      IvParameterSpec zeroIv = new IvParameterSpec(new byte[8]);
09         IvParameterSpec zeroIv = new IvParameterSpec(iv);
10         SecretKeySpec key = new SecretKeySpec(encryptKey.getBytes(), "DES");
11         Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
12         cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
13         byte[] encryptedData = cipher.doFinal(encryptString.getBytes());
14       
15         return Base64.encode(encryptedData);
16     }
17     public static String decryptDES(String decryptString, String decryptKey)throws Exception {
18         byte[] byteMi = new Base64().decode(decryptString);
19         IvParameterSpec zeroIv = new IvParameterSpec(iv);
20 //      IvParameterSpec zeroIv = new IvParameterSpec(new byte[8]);
21         SecretKeySpec key = new SecretKeySpec(decryptKey.getBytes(), "DES");
22         Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
23         cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);
24         byte decryptedData[] = cipher.doFinal(byteMi);
25       
26         return new String(decryptedData);
27     }
28 }

用到的BASE64工具类:
001 import java.io.ByteArrayOutputStream;
002 import java.io.IOException;
003 import java.io.OutputStream;
004  
005  
006  
007 public class Base64 {
008     private static final char[] legalChars ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
009     /**
010      * data[]进行编码
011      * @param data
012      * @return
013      */
014         public static String encode(byte[] data) {
015             int start = 0;
016             int len = data.length;
017             StringBuffer buf = new StringBuffer(data.length * 3 2);
018  
019             int end = len - 3;
020             int i = start;
021             int n = 0;
022  
023             while (i <= end) {
024                 int d = ((((int) data[i]) & 0x0ff) << 16)
025                         | ((((int) data[i + 1]) & 0x0ff) << 8)
026                         | (((int) data[i + 2]) & 0x0ff);
027  
028                 buf.append(legalChars[(d >> 18) & 63]);
029                 buf.append(legalChars[(d >> 12) & 63]);
030                 buf.append(legalChars[(d >> 6) & 63]);
031                 buf.append(legalChars[d & 63]);
032  
033                 i += 3;
034  
035                 if (n++ >= 14) {
036                     n = 0;
037                     buf.append(" ");
038                 }
039             }
040  
041             if (i == start + len - 2) {
042                 int d = ((((int) data[i]) & 0x0ff) << 16)
043                         | ((((int) data[i + 1]) & 255) << 8);
044  
045                 buf.append(legalChars[(d >> 18) & 63]);
046                 buf.append(legalChars[(d >> 12) & 63]);
047                 buf.append(legalChars[(d >> 6) & 63]);
048                 buf.append("=");
049             else if (i == start + len - 1) {
050                 int d = (((int) data[i]) & 0x0ff) << 16;
051  
052                 buf.append(legalChars[(d >> 18) & 63]);
053                 buf.append(legalChars[(d >> 12) & 63]);
054                 buf.append("==");
055             }
056  
057             return buf.toString();
058         }
059  
060         private static int decode(char c) {
061             if (c >= 'A' && c <= 'Z')
062                 return ((int) c) - 65;
063             else if (c >= 'a' && c <= 'z')
064                 return ((int) c) - 97 26;
065             else if (c >= '0' && c <= '9')
066                 return ((int) c) - 48 26 26;
067             else
068                 switch (c) {
069                 case '+':
070                     return 62;
071                 case '/':
072                     return 63;
073                 case '=':
074                     return 0;
075                 default:
076                     throw new RuntimeException("unexpected code: " + c);
077                 }
078         }
079  
080         /**
081          * Decodes the given Base64 encoded String to a new byte array. The byte
082          * array holding the decoded data is returned.
083          */
084  
085         public static byte[] decode(String s) {
086  
087             ByteArrayOutputStream bos = new ByteArrayOutputStream();
088             try {
089                 decode(s, bos);
090             catch (IOException e) {
091                 throw new RuntimeException();
092             }
093             byte[] decodedBytes = bos.toByteArray();
094             try {
095                 bos.close();
096                 bos = null;
097             catch (IOException ex) {
098                 System.err.println("Error while decoding BASE64: " + ex.toString());
099             }
100             return decodedBytes;
101         }
102  
103         private static void decode(String s, OutputStream os) throws IOException {
104             int i = 0;
105  
106             int len = s.length();
107  
108             while (true) {
109                 while (i < len && s.charAt(i) <= ' ')
110                     i++;
111  
112                 if (i == len)
113                     break;
114  
115                 int tri = (decode(s.charAt(i)) << 18)
116                         + (decode(s.charAt(i + 1)) << 12)
117                         + (decode(s.charAt(i + 2)) << 6)
118                         + (decode(s.charAt(i + 3)));
119  
120                 os.write((tri >> 16) & 255);
121                 if (s.charAt(i + 2) == '=')
122                     break;
123                 os.write((tri >> 8) & 255);
124                 if (s.charAt(i + 3) == '=')
125                     break;
126                 os.write(tri & 255);
127  
128                 i += 4;
129             }
130         }
131          
132 }

adnroid平台的主函数:
01 public class main extends Activity {
02     /** Called when the activity is first created. */
03     @Override
04     public void onCreate(Bundle savedInstanceState) {
05         super.onCreate(savedInstanceState);
06         setContentView(R.layout.main);
07         
08         String key = "12345678";
09         String text = "12345678";
10          
11          
12         try {
13             String result1 = DES.encryptDES(text,key);
14             String result2 = DES.decryptDES(result1, key);
15             Log.i("DES encode text is ", result1);
16             Log.i("DES encode text is ", result2);
17         catch (Exception e) {
18             // TODO Auto-generated catch block
19             e.printStackTrace();
20         }   
21     }
22 }

通过查看log日志就可以看到结果。

两个平台的结果是一样的,都是:

加密结果:X2p9Uo45Tzk6Ntu6W7Ev+Q==
解密结果:12345678

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值