[引]Android、iPhone和Java三个平台一致的加密工具 .

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

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

[java] view plaincopyprint?
01.package org.liuyq.des3;
02.
03.import java.security.Key;
04.
05.import javax.crypto.Cipher;
06.import javax.crypto.SecretKeyFactory;
07.import javax.crypto.spec.DESedeKeySpec;
08.import javax.crypto.spec.IvParameterSpec;
09.
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. }
64.}
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;

/**
* 3DES加密工具类
*
* @author liufeng
* @date 2012-10-11
*/
public class Des3 {
// 密钥
private final static String secretKey = "liuyunqiang@lx100$#365#$";
// 向量
private final static String iv = "01234567";
// 加解密统一使用的编码方式
private final static String encoding = "utf-8";

/**
* 3DES加密
*
* @param plainText 普通文本
* @return
* @throws Exception
*/
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);
}

/**
* 3DES解密
*
* @param encryptText 加密文本
* @return
* @throws Exception
*/
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] view plaincopyprint?
01.package org.liuyq.des3;
02.import java.io.ByteArrayOutputStream;
03.import java.io.IOException;
04.import java.io.OutputStream;
05.
06./**
07. * Base64编码工具类
08. *
09. * @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. }
125.}
package org.liuyq.des3;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
* Base64编码工具类
*
* @author liufeng
* @date 2012-10-11
*/
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);
}
}

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

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加密程序,源代码如下:

[plain] view plaincopyprint?
01.//
02.// DES3Util.h
03.// lx100-gz
04.//
05.// Created by 柳峰 on 12-10-10.
06.// Copyright 2012 http://blog.csdn.net/lyq8479. All rights reserved.
07.//
08.
09.#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
//
// DES3Util.h
// lx100-gz
//
// Created by 柳峰 on 12-10-10.
// Copyright 2012 http://blog.csdn.net/lyq8479. All rights reserved.
//

#import <Foundation/Foundation.h>


@interface DES3Util : NSObject {

}

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

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

@end
[plain] view plaincopyprint?
01.//
02.// DES3Util.m
03.// lx100-gz
04.//
05.// Created by 柳峰 on 12-9-17.
06.// Copyright 2012 http://blog.csdn.net/lyq8479. All rights reserved.
07.//
08.
09.#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
//
// DES3Util.m
// lx100-gz
//
// Created by 柳峰 on 12-9-17.
// Copyright 2012 http://blog.csdn.net/lyq8479. All rights reserved.
//

#import "DES3Util.h"
#import <CommonCrypto/CommonCryptor.h>
#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个平台调用同一套加密程序呢?
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值