Android、iPhone和Java三个平台一致的加密方法

开发 后端
先前一直在做安卓,最近要开发iPhone客户端,这其中遇到的最让人纠结的要属Java、Android和iPhone三个平台加解密不一致的问 题。因为手机端后台通常是用JAVA开发的Web Service,Android和iPhone客户端调用同样的Web Service接口,为了数据安全考虑,要对数据进行加密。

先前一直在做安卓,最近要开发iPhone客户端,这其中遇到的最让人纠结的要属Java、Android和iPhone三个平台加解密不一致的问 题。因为手机端后台通常是用JAVA开发的Web Service,Android和iPhone客户端调用同样的Web Service接口,为了数据安全考虑,要对数据进行加密。头疼的问题就来了,很难编写出一套加密程序,在3个平台间加解密的结果一致,总不能为 Android和iPhone两个客户端各写一套Web Service接口吧?我相信还会有很多朋友为此困惑,在此分享一套3DES加密程序,能够实现Java、Android和iPhone三个平台加解密一 致。

首先是JAVA端的加密工具类,它同样适用于Android端,无需任何修改,即可保证Java与Android端的加解密一致,并且中文不会乱码。

双击代码全选

  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.   * @author liufeng  
  14.   * @date 2012-10-11 
  15.   */ 
  16. public class Des3 {  
  17.      // 密钥  
  18.      private final static String secretKey = "liuyunqiang@lx100$#365#$" ;  
  19.      // 向量  
  20.      private final static String iv = "01234567" ;  
  21.      // 加解密统一使用的编码方式  
  22.      private final static String encoding = "utf-8" ;  
  23.         
  24.      /** 
  25.       * 3DES加密 
  26.       *  
  27.       * @param plainText 普通文本 
  28.       * @return 
  29.       * @throws Exception  
  30.       */ 
  31.      public static String encode(String plainText) throws Exception {  
  32.          Key deskey = null ;  
  33.          DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());  
  34.          SecretKeyFactory keyfactory = SecretKeyFactory.getInstance( "desede" );  
  35.          deskey = keyfactory.generateSecret(spec);  
  36.         
  37.          Cipher cipher = Cipher.getInstance( "desede/CBC/PKCS5Padding" );  
  38.          IvParameterSpec ips = new IvParameterSpec(iv.getBytes());  
  39.          cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);  
  40.          byte [] encryptData = cipher.doFinal(plainText.getBytes(encoding));  
  41.          return Base64.encode(encryptData);  
  42.      }  
  43.         
  44.      /** 
  45.       * 3DES解密 
  46.       *  
  47.       * @param encryptText 加密文本 
  48.       * @return 
  49.       * @throws Exception 
  50.       */ 
  51.      public static String decode(String encryptText) throws Exception {  
  52.          Key deskey = null ;  
  53.          DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());  
  54.          SecretKeyFactory keyfactory = SecretKeyFactory.getInstance( "desede" );  
  55.          deskey = keyfactory.generateSecret(spec);  
  56.          Cipher cipher = Cipher.getInstance( "desede/CBC/PKCS5Padding" );  
  57.          IvParameterSpec ips = new IvParameterSpec(iv.getBytes());  
  58.          cipher.init(Cipher.DECRYPT_MODE, deskey, ips);  
  59.         
  60.          byte [] decryptData = cipher.doFinal(Base64.decode(encryptText));  
  61.         
  62.          return new String(decryptData, encoding);  
  63.      }  

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

双击代码全选

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

#p#

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

  1. //  
  2. //  DES3Util.h  
  3. //  lx100-gz  
  4. //  
  5. //  Created by  柳峰 on 12-10-10.  
  6. //  Copyright 2012 http://blog.csdn.net/lyq8479. All rights reserved.  
  7. //  
  8.         
  9. #import <Foundation/Foundation.h>  
  10.         
  11.         
  12. @interface DES3Util : NSObject {  
  13.         
  14. }  
  15.         
  16. // 加密方法  
  17. + (NSString*)encrypt:(NSString*)plainText;  
  18.         
  19. // 解密方法  
  20. + (NSString*)decrypt:(NSString*)encryptText;  
  21.         
  22. @end 

双击代码全选

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

iPhone端的加密工具类中引入了“GTMBase64.h”,这是iOS平台的Base64编码工具类,见附件

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

原文链接:http://www.iteye.com/

责任编辑:陈四芳 来源: iteye.com
相关推荐

2022-09-22 07:27:49

IT/OT治理网络安全物联网安全

2022-09-25 23:37:48

比特币数字货币加密货币

2023-04-26 11:14:11

IT领导者远程工作

2021-12-25 00:10:00

加密货币比特币货币

2014-10-21 11:19:09

Windows 10微软

2009-06-26 10:10:00

Hibernate状态

2020-10-14 10:16:12

CIOIT技术

2015-07-01 15:27:06

云平台VM高可用

2020-07-02 09:22:29

Web开发大数据平台大数据

2022-05-07 10:51:42

DevOps左移应用程序

2011-12-20 10:41:36

程序员

2024-05-24 08:25:25

Android线性布局

2010-03-15 16:34:50

Python字典

2022-12-06 14:03:43

云采用云迁移

2021-09-02 00:18:44

iPhone手机iOS

2019-09-03 18:16:44

Android 10Google长甜品

2011-05-23 18:17:54

增加外链

2013-10-14 15:36:44

流程

2010-06-08 16:21:46

如何安装Opensus

2009-06-26 10:07:00

Hibernate状态
点赞
收藏

51CTO技术栈公众号