博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android、iPhone和Java三个平台一致的加密工具
阅读量:6239 次
发布时间:2019-06-22

本文共 7311 字,大约阅读时间需要 24 分钟。

hot3.png

移动开发中遇到的最让人纠结的要属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. import java.security.Key;

  3. import javax.crypto.Cipher;

  4. import javax.crypto.SecretKeyFactory;

  5. import javax.crypto.spec.DESedeKeySpec;

  6. import javax.crypto.spec.IvParameterSpec;

  7. /**

  8. * 3DES加密工具类

  9. */

  10. public class Des3 {

  11.         // 密钥

  12.         private final static String secretKey = "liuyunqiang@lx100$#365#$";

  13.         // 向量

  14.         private final static String iv = "01234567";

  15.         // 加解密统一使用的编码方式

  16.         private final static String encoding = "utf-8";

  17.         /**

  18.          * 3DES加密

  19.          * 

  20.          * plainText 普通文本

  21.          *

  22.          * Exception 

  23.          */

  24.         public static String encode(String plainText) throws Exception {

  25.                 Key deskey = null;

  26.                 DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());

  27.                 SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");

  28.                 deskey = keyfactory.generateSecret(spec);

  29.                 Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");

  30.                 IvParameterSpec ips = new IvParameterSpec(iv.getBytes());

  31.                 cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);

  32.                 byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding));

  33.                 return Base64.encode(encryptData);

  34.         }

  35.         /**

  36.          * 3DES解密

  37.          * 

  38.          * encryptText 加密文本

  39.          * @return

  40.          * @throws Exception

  41.          */

  42.         public static String decode(String encryptText) throws Exception {

  43.                 Key deskey = null;

  44.                 DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());

  45.                 SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");

  46.                 deskey = keyfactory.generateSecret(spec);

  47.                 Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");

  48.                 IvParameterSpec ips = new IvParameterSpec(iv.getBytes());

  49.                 cipher.init(Cipher.DECRYPT_MODE, deskey, ips);

  50.                 byte[] decryptData = cipher.doFinal(Base64.decode(encryptText));

  51.                 return new String(decryptData, encoding);

  52.         }

  53. }

复制代码

上面的加密工具类会使用到Base64这个类,该类的源代码如下: Java代码

  1. import java.io.ByteArrayOutputStream;

  2. import java.io.IOException;

  3. import java.io.OutputStream;

  4. /**

  5. * Base64编码工具类

  6. */

  7. public class Base64 {

  8.         private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();

  9.         public static String encode(byte[] data) {

  10.                 int start = 0;

  11.                 int len = data.length;

  12.                 StringBuffer buf = new StringBuffer(data.length * 3 / 2);

  13.                 int end = len - 3;

  14.                 int i = start;

  15.                 int n = 0;

  16.                 while (i <= end) {

  17.                         int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 0x0ff) << 8) | (((int) data[i + 2]) & 0x0ff);

  18.                         buf.append(legalChars[(d >> 18) & 63]);

  19.                         buf.append(legalChars[(d >> 12) & 63]);

  20.                         buf.append(legalChars[(d >> 6) & 63]);

  21.                         buf.append(legalChars[d & 63]);

  22.                         i += 3;

  23.                         if (n++ >= 14) {

  24.                                 n = 0;

  25.                                 buf.append(" ");

  26.                         }

  27.                 }

  28.                 if (i == start + len - 2) {

  29.                         int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 255) << 8);

  30.                         buf.append(legalChars[(d >> 18) & 63]);

  31.                         buf.append(legalChars[(d >> 12) & 63]);

  32.                         buf.append(legalChars[(d >> 6) & 63]);

  33.                         buf.append("=");

  34.                 } else if (i == start + len - 1) {

  35.                         int d = (((int) data[i]) & 0x0ff) << 16;

  36.                         buf.append(legalChars[(d >> 18) & 63]);

  37.                         buf.append(legalChars[(d >> 12) & 63]);

  38.                         buf.append("==");

  39.                 }

  40.                 return buf.toString();

  41.         }

  42.         private static int decode(char c) {

  43.                 if (c >= 'A' && c <= 'Z')

  44.                         return ((int) c) - 65;

  45.                 else if (c >= 'a' && c <= 'z')

  46.                         return ((int) c) - 97 + 26;

  47.                 else if (c >= '0' && c <= '9')

  48.                         return ((int) c) - 48 + 26 + 26;

  49.                 else

  50.                         switch (c) {

  51.                         case '+':

  52.                                 return 62;

  53.                         case '/':

  54.                                 return 63;

  55.                         case '=':

  56.                                 return 0;

  57.                         default:

  58.                                 throw new RuntimeException("unexpected code: " + c);

  59.                         }

  60.         }

  61.         /**

  62.          * Decodes the given Base64 encoded String to a new byte array. The byte array holding the decoded data is returned.

  63.          */

  64.         public static byte[] decode(String s) {

  65.                 ByteArrayOutputStream bos = new ByteArrayOutputStream();

  66.                 try {

  67.                         decode(s, bos);

  68.                 } catch (IOException e) {

  69.                         throw new RuntimeException();

  70.                 }

  71.                 byte[] decodedBytes = bos.toByteArray();

  72.                 try {

  73.                         bos.close();

  74.                         bos = null;

  75.                 } catch (IOException ex) {

  76.                         System.err.println("Error while decoding BASE64: " + ex.toString());

  77.                 }

  78.                 return decodedBytes;

  79.         }

  80.         private static void decode(String s, OutputStream os) throws IOException {

  81.                 int i = 0;

  82.                 int len = s.length();

  83.                 while (true) {

  84.                         while (i < len && s.charAt(i) <= ' ')

  85.                                 i++;

  86.                         if (i == len)

  87.                                 break;

  88.                         int tri = (decode(s.charAt(i)) << 18) + (decode(s.charAt(i + 1)) << 12) + (decode(s.charAt(i + 2)) << 6) + (decode(s.charAt(i + 3)));

  89.                         os.write((tri >> 16) & 255);

  90.                         if (s.charAt(i + 2) == '=')

  91.                                 break;

  92.                         os.write((tri >> 8) & 255);

  93.                         if (s.charAt(i + 3) == '=')

  94.                                 break;

  95.                         os.write(tri & 255);

  96.                         i += 4;

  97.                 }

  98.         }

  99. }

复制代码

接下来是iPhone端的加密程序,当然是用Ojbective-C写的3DES加密程序,源代码如下: 

Java代码

  1. //

  2. //  DES3Util.h

  3. //

  4. #import <Foundation/Foundation.h>

  5. @interface DES3Util : NSObject {

  6. }

  7. // 加密方法

  8. + (NSString*)encrypt:(NSString*)plainText;

  9. // 解密方法

  10. + (NSString*)decrypt:(NSString*)encryptText;

  11. @end

复制代码

Java代码

  1. //

  2. //  DES3Util.m

  3. //

  4. #import "DES3Util.h"

  5. #import <CommonCrypto/CommonCryptor.h>

  6. #import "GTMBase64.h"

  7. #define gkey                        @"liuyunqiang@lx100$#365#$"

  8. #define gIv             @"01234567"

  9. @implementation DES3Util

  10. // 加密方法

  11. + (NSString*)encrypt:(NSString*)plainText {

  12.     NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];

  13.         size_t plainTextBufferSize = [data length];

  14.         const void *vplainText = (const void *)[data bytes];

  15.     

  16.     CCCryptorStatus ccStatus;

  17.     uint8_t *bufferPtr = NULL;

  18.     size_t bufferPtrSize = 0;

  19.     size_t movedBytes = 0;

  20.     

  21.     bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);

  22.     bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));

  23.     memset((void *)bufferPtr, 0x0, bufferPtrSize);

  24.     

  25.     const void *vkey = (const void *) [gkey UTF8String];

  26.     const void *vinitVec = (const void *) [gIv UTF8String];

  27.     

  28.     ccStatus = CCCrypt(kCCEncrypt,

  29.                        kCCAlgorithm3DES,

  30.                        kCCOptionPKCS7Padding,

  31.                        vkey,

  32.                        kCCKeySize3DES,

  33.                        vinitVec,

  34.                        vplainText,

  35.                        plainTextBufferSize,

  36.                        (void *)bufferPtr,

  37.                        bufferPtrSize,

  38.                        &movedBytes);

  39.     

  40.     NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];

  41.         NSString *result = [GTMBase64 stringByEncodingData:myData];

  42.     return result;

  43. }

  44. // 解密方法

  45. + (NSString*)decrypt:(NSString*)encryptText {

  46.     NSData *encryptData = [GTMBase64 decodeData:[encryptText dataUsingEncoding:NSUTF8StringEncoding]];

  47.         size_t plainTextBufferSize = [encryptData length];

  48.         const void *vplainText = [encryptData bytes];

  49.     

  50.     CCCryptorStatus ccStatus;

  51.     uint8_t *bufferPtr = NULL;

  52.     size_t bufferPtrSize = 0;

  53.     size_t movedBytes = 0;

  54.     

  55.     bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);

  56.     bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));

  57.     memset((void *)bufferPtr, 0x0, bufferPtrSize);

  58.     

  59.     const void *vkey = (const void *) [gkey UTF8String];

  60.     const void *vinitVec = (const void *) [gIv UTF8String];

  61.     

  62.     ccStatus = CCCrypt(kCCDecrypt,

  63.                        kCCAlgorithm3DES,

  64.                        kCCOptionPKCS7Padding,

  65.                        vkey,

  66.                        kCCKeySize3DES,

  67.                        vinitVec,

  68.                        vplainText,

  69.                        plainTextBufferSize,

  70.                        (void *)bufferPtr,

  71.                        bufferPtrSize,

  72.                        &movedBytes);

  73.     

  74.     NSString *result = [[[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr

  75.                                                                 length:(NSUInteger)movedBytes] encoding:NSUTF8StringEncoding] autorelease];

  76.     return result;

  77. }

  78. @end

复制代码

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

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

转载于:https://my.oschina.net/1590538xiaokai/blog/357939

你可能感兴趣的文章
【工具使用系列】关于 MATLAB 遗传算法与直接搜索工具箱,你需要知道的事
查看>>
Kali-linux Arpspoof工具
查看>>
PDF文档页面如何重新排版?
查看>>
基于http协议使用protobuf进行前后端交互
查看>>
bash腳本編程之三 条件判断及算数运算
查看>>
php cookie
查看>>
linux下redis安装
查看>>
量子通信和大数据最有市场突破前景
查看>>
如何申请开通微信多客服功能
查看>>
Sr_C++_Engineer_(LBS_Engine@Global Map Dept.)
查看>>
非监督学习算法:异常检测
查看>>
jquery的checkbox,radio,select等方法总结
查看>>
Linux coredump
查看>>
Ubuntu 10.04安装水晶(Mercury)无线网卡驱动
查看>>
我的友情链接
查看>>
ElasticSearch 2 (32) - 信息聚合系列之范围限定
查看>>
VS2010远程调试C#程序
查看>>
[MicroPython]TurniBit开发板DIY自动窗帘模拟系统
查看>>
从Handler.post(Runnable r)再一次梳理Android的消息机制(以及handler的内存泄露)
查看>>
windows查看端口占用
查看>>