ios java 3DES 加解密

来源:互联网 发布:源mac地址的作用 编辑:程序博客网 时间:2024/05/12 11:13
 移动开发中遇到的最让人纠结的要属Java、Android和iPhone三个平台加解密不一致的问题。因为手机端后台通常是用JAVA开发的Web Service,Android和iPhone客户端调用同样的Web Service接口,为了数据安全考虑,要对数据进行加密。头疼的问题就来了,很难编写出一套加密程序,在3个平台间加解密的结果一致,总不能为Android和iPhone两个客户端各写一套Web Service接口吧?我相信还会有很多朋友为此困惑,在此分享一套3DES加密程序,能够实现Java、Android和iPhone三个平台加解密一致。 

        首先是JAVA端的加密工具类,它同样适用于Android端,无需任何修改,即可保证Java与Android端的加解密一致,并且中文不会乱码。 
Java代码  收藏代码
  1. package org.liuyq.des3;  
  2.   
  3. import java.security.Key;  
  4.   
  5. import javax.crypto.Cipher;  
  6. import javax.crypto.SecretKeyFactory;  
  7. import javax.crypto.spec.DESedeKeySpec;  
  8. import javax.crypto.spec.IvParameterSpec;  
  9.   
  10. /** 
  11.  * 3DES加密工具类 
  12.  */  
  13. public class Des3 {  
  14.     // 密钥  
  15.     private final static String secretKey = "liuyunqiang@lx100$#365#$";  
  16.     // 向量  
  17.     private final static String iv = "01234567";  
  18.     // 加解密统一使用的编码方式  
  19.     private final static String encoding = "utf-8";  
  20.   
  21.     /** 
  22.      * 3DES加密 
  23.      *  
  24.      * @param plainText 普通文本 
  25.      * @return 
  26.      * @throws Exception  
  27.      */  
  28.     public static String encode(String plainText) throws Exception {  
  29.         Key deskey = null;  
  30.         DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());  
  31.         SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");  
  32.         deskey = keyfactory.generateSecret(spec);  
  33.   
  34.         Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");  
  35.         IvParameterSpec ips = new IvParameterSpec(iv.getBytes());  
  36.         cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);  
  37.         byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding));  
  38.         return Base64.encode(encryptData);  
  39.     }  
  40.   
  41.     /** 
  42.      * 3DES解密 
  43.      *  
  44.      * @param encryptText 加密文本 
  45.      * @return 
  46.      * @throws Exception 
  47.      */  
  48.     public static String decode(String encryptText) throws Exception {  
  49.         Key deskey = null;  
  50.         DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());  
  51.         SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");  
  52.         deskey = keyfactory.generateSecret(spec);  
  53.         Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");  
  54.         IvParameterSpec ips = new IvParameterSpec(iv.getBytes());  
  55.         cipher.init(Cipher.DECRYPT_MODE, deskey, ips);  
  56.   
  57.         byte[] decryptData = cipher.doFinal(Base64.decode(encryptText));  
  58.   
  59.         return new String(decryptData, encoding);  
  60.     }  
  61. }  


上面的加密工具类会使用到Base64这个类,该类的源代码如下: 
Java代码  收藏代码
  1. import java.io.ByteArrayOutputStream;  
  2. import java.io.IOException;  
  3. import java.io.OutputStream;  
  4.   
  5. /** 
  6.  * Base64编码工具类 
  7.  */  
  8. public class Base64 {  
  9.     private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();  
  10.   
  11.     public static String encode(byte[] data) {  
  12.         int start = 0;  
  13.         int len = data.length;  
  14.         StringBuffer buf = new StringBuffer(data.length * 3 / 2);  
  15.   
  16.         int end = len - 3;  
  17.         int i = start;  
  18.         int n = 0;  
  19.   
  20.         while (i <= end) {  
  21.             int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 0x0ff) << 8) | (((int) data[i + 2]) & 0x0ff);  
  22.   
  23.             buf.append(legalChars[(d >> 18) & 63]);  
  24.             buf.append(legalChars[(d >> 12) & 63]);  
  25.             buf.append(legalChars[(d >> 6) & 63]);  
  26.             buf.append(legalChars[d & 63]);  
  27.   
  28.             i += 3;  
  29.   
  30.             if (n++ >= 14) {  
  31.                 n = 0;  
  32.                 buf.append(" ");  
  33.             }  
  34.         }  
  35.   
  36.         if (i == start + len - 2) {  
  37.             int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 255) << 8);  
  38.   
  39.             buf.append(legalChars[(d >> 18) & 63]);  
  40.             buf.append(legalChars[(d >> 12) & 63]);  
  41.             buf.append(legalChars[(d >> 6) & 63]);  
  42.             buf.append("=");  
  43.         } else if (i == start + len - 1) {  
  44.             int d = (((int) data[i]) & 0x0ff) << 16;  
  45.   
  46.             buf.append(legalChars[(d >> 18) & 63]);  
  47.             buf.append(legalChars[(d >> 12) & 63]);  
  48.             buf.append("==");  
  49.         }  
  50.   
  51.         return buf.toString();  
  52.     }  
  53.   
  54.     private static int decode(char c) {  
  55.         if (c >= 'A' && c <= 'Z')  
  56.             return ((int) c) - 65;  
  57.         else if (c >= 'a' && c <= 'z')  
  58.             return ((int) c) - 97 + 26;  
  59.         else if (c >= '0' && c <= '9')  
  60.             return ((int) c) - 48 + 26 + 26;  
  61.         else  
  62.             switch (c) {  
  63.             case '+':  
  64.                 return 62;  
  65.             case '/':  
  66.                 return 63;  
  67.             case '=':  
  68.                 return 0;  
  69.             default:  
  70.                 throw new RuntimeException("unexpected code: " + c);  
  71.             }  
  72.     }  
  73.   
  74.     /** 
  75.      * Decodes the given Base64 encoded String to a new byte array. The byte array holding the decoded data is returned. 
  76.      */  
  77.   
  78.     public static byte[] decode(String s) {  
  79.   
  80.         ByteArrayOutputStream bos = new ByteArrayOutputStream();  
  81.         try {  
  82.             decode(s, bos);  
  83.         } catch (IOException e) {  
  84.             throw new RuntimeException();  
  85.         }  
  86.         byte[] decodedBytes = bos.toByteArray();  
  87.         try {  
  88.             bos.close();  
  89.             bos = null;  
  90.         } catch (IOException ex) {  
  91.             System.err.println("Error while decoding BASE64: " + ex.toString());  
  92.         }  
  93.         return decodedBytes;  
  94.     }  
  95.   
  96.     private static void decode(String s, OutputStream os) throws IOException {  
  97.         int i = 0;  
  98.   
  99.         int len = s.length();  
  100.   
  101.         while (true) {  
  102.             while (i < len && s.charAt(i) <= ' ')  
  103.                 i++;  
  104.   
  105.             if (i == len)  
  106.                 break;  
  107.   
  108.             int tri = (decode(s.charAt(i)) << 18) + (decode(s.charAt(i + 1)) << 12) + (decode(s.charAt(i + 2)) << 6) + (decode(s.charAt(i + 3)));  
  109.   
  110.             os.write((tri >> 16) & 255);  
  111.             if (s.charAt(i + 2) == '=')  
  112.                 break;  
  113.             os.write((tri >> 8) & 255);  
  114.             if (s.charAt(i + 3) == '=')  
  115.                 break;  
  116.             os.write(tri & 255);  
  117.   
  118.             i += 4;  
  119.         }  
  120.     }  
  121. }  


接下来是iPhone端的加密程序,当然是用Ojbective-C写的3DES加密程序,源代码如下: 
Java代码  收藏代码
  1. //  
  2. //  DES3Util.h  
  3. //  
  4.   
  5. #import <Foundation/Foundation.h>  
  6.   
  7.   
  8. @interface DES3Util : NSObject {  
  9.   
  10. }  
  11.   
  12. // 加密方法  
  13. + (NSString*)encrypt:(NSString*)plainText;  
  14.   
  15. // 解密方法  
  16. + (NSString*)decrypt:(NSString*)encryptText;  
  17.   
  18. @end  


Java代码  收藏代码
  1. //  
  2. //  DES3Util.m  
  3. //  
  4.   
  5. #import "DES3Util.h"  
  6. #import <CommonCrypto/CommonCryptor.h>  
  7. #import "GTMBase64.h"  
  8.   
  9. #define gkey            @"liuyunqiang@lx100$#365#$"  
  10. #define gIv             @"01234567"  
  11.   
  12. @implementation DES3Util  
  13.   
  14. // 加密方法  
  15. + (NSString*)encrypt:(NSString*)plainText {  
  16.     NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];  
  17.     size_t plainTextBufferSize = [data length];  
  18.     const void *vplainText = (const void *)[data bytes];  
  19.       
  20.     CCCryptorStatus ccStatus;  
  21.     uint8_t *bufferPtr = NULL;  
  22.     size_t bufferPtrSize = 0;  
  23.     size_t movedBytes = 0;  
  24.       
  25.     bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);  
  26.     bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));  
  27.     memset((void *)bufferPtr, 0x0, bufferPtrSize);  
  28.       
  29.     const void *vkey = (const void *) [gkey UTF8String];  
  30.     const void *vinitVec = (const void *) [gIv UTF8String];  
  31.       
  32.     ccStatus = CCCrypt(kCCEncrypt,  
  33.                        kCCAlgorithm3DES,  
  34.                        kCCOptionPKCS7Padding|kCCOptionECBMode,  
  35.                        vkey,  
  36.                        kCCKeySize3DES,  
  37.                        vinitVec,  
  38.                        vplainText,  
  39.                        plainTextBufferSize,  
  40.                        (void *)bufferPtr,  
  41.                        bufferPtrSize,  
  42.                        &movedBytes);  
  43.       
  44.     NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];  
  45.     NSString *result = [GTMBase64 stringByEncodingData:myData];  
  46.     return result;  
  47. }  
  48.   
  49. // 解密方法  
  50. + (NSString*)decrypt:(NSString*)encryptText {  
  51.     NSData *encryptData = [GTMBase64 decodeData:[encryptText dataUsingEncoding:NSUTF8StringEncoding]];  
  52.     size_t plainTextBufferSize = [encryptData length];  
  53.     const void *vplainText = [encryptData bytes];  
  54.       
  55.     CCCryptorStatus ccStatus;  
  56.     uint8_t *bufferPtr = NULL;  
  57.     size_t bufferPtrSize = 0;  
  58.     size_t movedBytes = 0;  
  59.       
  60.     bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);  
  61.     bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));  
  62.     memset((void *)bufferPtr, 0x0, bufferPtrSize);  
  63.       
  64.     const void *vkey = (const void *) [gkey UTF8String];  
  65.     const void *vinitVec = (const void *) [gIv UTF8String];  
  66.       
  67.     ccStatus = CCCrypt(kCCDecrypt,  
  68.                        kCCAlgorithm3DES,  
  69.                        kCCOptionPKCS7Padding,  
  70.                        vkey,  
  71.                        kCCKeySize3DES,  
  72.                        vinitVec,  
  73.                        vplainText,  
  74.                        plainTextBufferSize,  
  75.                        (void *)bufferPtr,  
  76.                        bufferPtrSize,  
  77.                        &movedBytes);  
  78.       
  79.     NSString *result = [[[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr   
  80.                                 length:(NSUInteger)movedBytes] encoding:NSUTF8StringEncoding] autorelease];  
  81.     return result;  
  82. }  
  83.   
  84. @end  


iPhone端的加密工具类中引入了“GTMBase64.h”,这是iOS平台的Base64编码工具类,就不在这里贴出相关代码了,需要的百度一下就能找到。 

        这样,JAVA,Android和iPhone三个平台的加密不一致问题就可以解决了。其实,对此问题,还有一种更好的实现方式,那就是用C语言写一套加密程序,这样在iOS平台是可以直接使用C程序的,而在Java和Android端通过JNI去调用C语言编写的加密方法,这样也可以实现3个平台调用同一套加密程序。 

借鉴地址:http://blog.csdn.net/lyq8479/article/details/8062867
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 闲鱼买的东西确认收货有问题怎么办 不让微信好友看到吃鸡的名字怎么办 金鹰贵宾积分卡过期了怎么办 小宝机器人一直停在联网界面怎么办 手机版的有道云笔记忘记邮箱怎么办 钡灌肠复查钡剂排空不良怎么办 两个月宝宝灌肠后不排便怎么办 一岁宝宝肠套叠灌肠后拉肚子怎么办 苹果手机自带的天气没有了怎么办? 衣服在洗衣机里忘记拿出来怎么办 苹果se手机系统占内存太大怎么办 客人把饭店老板打了民警怎么办 商场嫌品牌低端不让入驻怎么办 带着孩子坐飞机座位不在一起怎么办 公司老板跑路了员工该怎么办 超市买的衣服防盗扣忘记取了怎么办 在超市买的衣服那个扣没取怎么办啊 超市散称商品条码老记不住怎么办 app账号密码忘记了怎么办注销难 幼儿老师遇到家长比较孩子该怎么办 发的微信公众号内容重复了怎么办 招嫖诈骗微信转账被骗怎么办 朋友在深圳龙岗被传销骗了要怎么办 怀疑家里人被传销组织骗去了怎么办 怀疑家人被骗进传销了该怎么办 b本扣3分了怎么办2018 抖音里面就剩人头的视频怎么办 自学参加普通高考那小高考怎么办 如果小学生长胸只长了一个该怎么办 脸上毛多导致的毛孔粗怎么办 吃了激素药头发掉的厉害怎么办 剪发的剪子中间的螺丝扣总掉怎么办 染完头发后一段时间长新头发怎么办 睡觉头发老被老公压着怎么办 漆盖关节不自在怎么办?吃什么好 摆床头的位置后面是弧形位怎么办 君子兰的根全烂掉了只剩茎怎么办 老板不发工资怎么办 没签合同的 牙套粘在牙齿上的松了怎么办 缝的线长在肉里怎么办 小孩喜欢用舌头顶牙齿缝怎么办