Android、iPhone和Java三个平台一…

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

              首先是JAVA端的加密工具类,它同样适用于Android端,无需任何修改,即可保证Java与Android端的加解密一致,并且中文不会乱码。
Java代码 复制代码  收藏代码Android、iPhone和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. public class Des3 {   
  12.     // 密钥   
  13.     private final static String secretKey "liuyunqiang@lx100$#365#$";   
  14.     // 向量   
  15.     private final static String iv "01234567";   
  16.     // 加解密统一使用的编码方式   
  17.     private final static String encoding "utf-8";   
  18.   
  19.       
  20.     public static String encode(String plainText) throws Exception {   
  21.         Key deskey null;   
  22.         DESedeKeySpec spec new DESedeKeySpec(secretKey.getBytes());   
  23.         SecretKeyFactory keyfactory SecretKeyFactory.getInstance("desede");   
  24.         deskey keyfactory.generateSecret(spec);   
  25.   
  26.         Cipher cipher Cipher.getInstance("desede/CBC/PKCS5Padding");   
  27.         IvParameterSpec ips new IvParameterSpec(iv.getBytes());   
  28.         cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);   
  29.         byte[] encryptData cipher.doFinal(plainText.getBytes(encoding));   
  30.         return Base64.encode(encryptData);   
  31.     }   
  32.   
  33.       
  34.     public static String decode(String encryptText) throws Exception {   
  35.         Key deskey null;   
  36.         DESedeKeySpec spec new DESedeKeySpec(secretKey.getBytes());   
  37.         SecretKeyFactory keyfactory SecretKeyFactory.getInstance("desede");   
  38.         deskey keyfactory.generateSecret(spec);   
  39.         Cipher cipher Cipher.getInstance("desede/CBC/PKCS5Padding");   
  40.         IvParameterSpec ips new IvParameterSpec(iv.getBytes());   
  41.         cipher.init(Cipher.DECRYPT_MODE, deskey, ips);   
  42.   
  43.         byte[] decryptData cipher.doFinal(Base64.decode(encryptText));   
  44.   
  45.         return new String(decryptData, encoding);   
  46.     }   
  47.  
package org.liuyq.des3;

import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;


public class Des3 {
        // 密钥
        private final static String secretKey = "liuyunqiang@lx100$#365#$";
        // 向量
        private final static String iv = "01234567";
        // 加解密统一使用的编码方式
        private final static String encoding = "utf-8";

        
        public static String encode(String plainText) throws Exception {
                Key deskey = null;
                DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
                SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
                deskey = keyfactory.generateSecret(spec);

                Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
                IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
                cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
                byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding));
                return Base64.encode(encryptData);
        }

        
        public static String decode(String encryptText) throws Exception {
                Key deskey = null;
                DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
                SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
                deskey = keyfactory.generateSecret(spec);
                Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
                IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
                cipher.init(Cipher.DECRYPT_MODE, deskey, ips);

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

                return new String(decryptData, encoding);
        }
}



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


public class Base64 {
        private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();

        public static String encode(byte[] data) {
                int start = 0;
                int len = data.length;
                StringBuffer buf = new StringBuffer(data.length * 3 / 2);

                int end = len - 3;
                int i = start;
                int n = 0;

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

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

                        i += 3;

                        if (n++ >= 14) {
                                n = 0;
                                buf.append(" ");
                        }
                }

                if (i == start + len - 2) {
                        int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 255) << 8);

                        buf.append(legalChars[(d >> 18) & 63]);
                        buf.append(legalChars[(d >> 12) & 63]);
                        buf.append(legalChars[(d >> 6) & 63]);
                        buf.append("=");
                } else if (i == start + len - 1) {
                        int d = (((int) data[i]) & 0x0ff) << 16;

                        buf.append(legalChars[(d >> 18) & 63]);
                        buf.append(legalChars[(d >> 12) & 63]);
                        buf.append("==");
                }

                return buf.toString();
        }

        private static int decode(char c) {
                if (c >= 'A' && c <= 'Z')
                        return ((int) c) - 65;
                else if (c >= 'a' && c <= 'z')
                        return ((int) c) - 97 + 26;
                else if (c >= '0' && c <= '9')
                        return ((int) c) - 48 + 26 + 26;
                else
                        switch (c) {
                        case '+':
                                return 62;
                        case '/':
                                return 63;
                        case '=':
                                return 0;
                        default:
                                throw new RuntimeException("unexpected code: " + c);
                        }
        }

        

        public static byte[] decode(String s) {

                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                try {
                        decode(s, bos);
                } catch (IOException e) {
                        throw new RuntimeException();
                }
                byte[] decodedBytes = bos.toByteArray();
                try {
                        bos.close();
                        bos = null;
                } catch (IOException ex) {
                        System.err.println("Error while decoding BASE64: " + ex.toString());
                }
                return decodedBytes;
        }

        private static void decode(String s, OutputStream os) throws IOException {
                int i = 0;

                int len = s.length();

                while (true) {
                        while (i < len && s.charAt(i) <= ' ')
                                i++;

                        if (i == len)
                                break;

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

                        os.write((tri >> 16) & 255);
                        if (s.charAt(i + 2) == '=')
                                break;
                        os.write((tri >> 8) & 255);
                        if (s.charAt(i + 3) == '=')
                                break;
                        os.write(tri & 255);

                        i += 4;
                }
        }
}



接下来是iPhone端的加密程序,当然是用Ojbective-C写的3DES加密程序,源代码如下:
Java代码 复制代码  收藏代码Android、iPhone和Java三个平台一致的加密工具
  1. //   
  2. //  DES3Util.h   
  3. //   
  4.   
  5. #import    
  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  
//
//  DES3Util.h
//

#import 


@interface DES3Util : NSObject {

}

// 加密方法
+ (NSString*)encrypt:(NSString*)plainText;

// 解密方法
+ (NSString*)decrypt:(NSString*)encryptText;

@end



Java代码 复制代码  收藏代码Android、iPhone和Java三个平台一致的加密工具
  1. //   
  2. //  DES3Util.m   
  3. //   
  4.   
  5. #import "DES3Util.h"  
  6. #import    
  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,   
  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  
//
//  DES3Util.m
//

#import "DES3Util.h"
#import 
#import "GTMBase64.h"

#define gkey                    @"liuyunqiang@lx100$#365#$"
#define gIv             @"01234567"

@implementation DES3Util

// 加密方法
+ (NSString*)encrypt:(NSString*)plainText {
    NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
        size_t plainTextBufferSize = [data length];
        const void *vplainText = (const void *)[data bytes];
    
    CCCryptorStatus ccStatus;
    uint8_t *bufferPtr = NULL;
    size_t bufferPtrSize = 0;
    size_t movedBytes = 0;
    
    bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
    bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
    memset((void *)bufferPtr, 0x0, bufferPtrSize);
    
    const void *vkey = (const void *) [gkey UTF8String];
    const void *vinitVec = (const void *) [gIv UTF8String];
    
    ccStatus = CCCrypt(kCCEncrypt,
                       kCCAlgorithm3DES,
                       kCCOptionPKCS7Padding,
                       vkey,
                       kCCKeySize3DES,
                       vinitVec,
                       vplainText,
                       plainTextBufferSize,
                       (void *)bufferPtr,
                       bufferPtrSize,
                       &movedBytes);
    
    NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
        NSString *result = [GTMBase64 stringByEncodingData:myData];
    return result;
}

// 解密方法
+ (NSString*)decrypt:(NSString*)encryptText {
    NSData *encryptData = [GTMBase64 decodeData:[encryptText dataUsingEncoding:NSUTF8StringEncoding]];
        size_t plainTextBufferSize = [encryptData length];
        const void *vplainText = [encryptData bytes];
    
    CCCryptorStatus ccStatus;
    uint8_t *bufferPtr = NULL;
    size_t bufferPtrSize = 0;
    size_t movedBytes = 0;
    
    bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
    bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
    memset((void *)bufferPtr, 0x0, bufferPtrSize);
    
    const void *vkey = (const void *) [gkey UTF8String];
    const void *vinitVec = (const void *) [gIv UTF8String];
    
    ccStatus = CCCrypt(kCCDecrypt,
                       kCCAlgorithm3DES,
                       kCCOptionPKCS7Padding,
                       vkey,
                       kCCKeySize3DES,
                       vinitVec,
                       vplainText,
                       plainTextBufferSize,
                       (void *)bufferPtr,
                       bufferPtrSize,
                       &movedBytes);
    
    NSString *result = [[[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr 
                                                                length:(NSUInteger)movedBytes] encoding:NSUTF8StringEncoding] autorelease];
    return result;
}

@end


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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值