1、找到文件
下載地址:https://yunpan.cn/ckxIZwyppN3Pb (提取碼:23cd)
2、導入文件
由于這兩個文件不不支持ARC,因此應該為GTMBase64.m 和 DES3Util.m添加編譯標記-fno-objc-arc進行局部ARC禁止。
3、加密后打印出來結果
4、修改明文
這其中遇到的最讓人糾結的要屬Java、Android和iPhone三個平臺加解密不一致的問題。因為手機端后臺通常是用JAVA開發的Web Service,Android和iPhone客戶端調用同樣的Web Service接口,為了數據安全考慮,要對數據進行加密。頭疼的問題就來了,很難編寫出一套加密程序,在3個平臺間加解密的結果一致,總不能為Android和iPhone兩個客戶端各寫一套Web Service接口吧?我相信還會有很多朋友為此困惑,在此分享一套3DES加密程序,能夠實現Java、Android和iPhone三個平臺加解密一致。
首先是JAVA端的加密工具類,它同樣適用于Android端,無需任何修改,即可保證Java與Android端的加解密一致,并且中文不會亂碼。
packageorg.liuyq.des3;
importjava.security.Key;
importjavax.crypto.Cipher;
importjavax.crypto.SecretKeyFactory;
importjavax.crypto.spec.DESedeKeySpec;
importjavax.crypto.spec.IvParameterSpec;
/**
*?3DES加密工具類
*
*?@author?liufeng
*?@date?2012-10-11
*/
publicclassDes3?{
//?密鑰
privatefinalstaticString?secretKey?="liuyunqiang@lx100$#365#$";
//?向量
privatefinalstaticString?iv?="01234567";
//?加解密統一使用的編碼方式
privatefinalstaticString?encoding?="utf-8";
/**
*?3DES加密
*
*?@param?plainText?普通文本
*?@return
*?@throws?Exception
*/
publicstaticString?encode(String?plainText)throwsException?{
Key?deskey?=null;
DESedeKeySpec?spec?=newDESedeKeySpec(secretKey.getBytes());
SecretKeyFactory?keyfactory?=?SecretKeyFactory.getInstance("desede");
deskey?=?keyfactory.generateSecret(spec);
Cipher?cipher?=?Cipher.getInstance("desede/CBC/PKCS5Padding");
IvParameterSpec?ips?=newIvParameterSpec(iv.getBytes());
cipher.init(Cipher.ENCRYPT_MODE,?deskey,?ips);
byte[]?encryptData?=?cipher.doFinal(plainText.getBytes(encoding));
returnBase64.encode(encryptData);
}
/**
*?3DES解密
*
*?@param?encryptText?加密文本
*?@return
*?@throws?Exception
*/
publicstaticString?decode(String?encryptText)throwsException?{
Key?deskey?=null;
DESedeKeySpec?spec?=newDESedeKeySpec(secretKey.getBytes());
SecretKeyFactory?keyfactory?=?SecretKeyFactory.getInstance("desede");
deskey?=?keyfactory.generateSecret(spec);
Cipher?cipher?=?Cipher.getInstance("desede/CBC/PKCS5Padding");
IvParameterSpec?ips?=newIvParameterSpec(iv.getBytes());
cipher.init(Cipher.DECRYPT_MODE,?deskey,?ips);
byte[]?decryptData?=?cipher.doFinal(Base64.decode(encryptText));
returnnewString(decryptData,?encoding);
}
}
上面的加密工具類會使用到Base64這個類,該類的源代碼如下:
packageorg.liuyq.des3;
importjava.io.ByteArrayOutputStream;
importjava.io.IOException;
importjava.io.OutputStream;
/**
*?Base64編碼工具類
*
*?@author?liufeng
*?@date?2012-10-11
*/
publicclassBase64?{
privatestaticfinalchar[]?legalChars?="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
publicstaticString?encode(byte[]?data)?{
intstart?=0;
intlen?=?data.length;
StringBuffer?buf?=newStringBuffer(data.length?*3/2);
intend?=?len?-3;
inti?=?start;
intn?=0;
while(i?<=?end)?{
intd?=?((((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)?{
intd?=?((((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("=");
}elseif(i?==?start?+?len?-1)?{
intd?=?(((int)?data[i])?&0x0ff)?<<16;
buf.append(legalChars[(d?>>18)?&63]);
buf.append(legalChars[(d?>>12)?&63]);
buf.append("==");
}
returnbuf.toString();
}
privatestaticintdecode(charc)?{
if(c?>='A'&&?c?<='Z')
return((int)?c)?-65;
elseif(c?>='a'&&?c?<='z')
return((int)?c)?-97+26;
elseif(c?>='0'&&?c?<='9')
return((int)?c)?-48+26+26;
else
switch(c)?{
case'+':
return62;
case'/':
return63;
case'=':
return0;
default:
thrownewRuntimeException("unexpected?code:?"+?c);
}
}
/**
*?Decodes?the?given?Base64?encoded?String?to?a?new?byte?array.?The?byte?array?holding?the?decoded?data?is?returned.
*/
publicstaticbyte[]?decode(String?s)?{
ByteArrayOutputStream?bos?=newByteArrayOutputStream();
try{
decode(s,?bos);
}catch(IOException?e)?{
thrownewRuntimeException();
}
byte[]?decodedBytes?=?bos.toByteArray();
try{
bos.close();
bos?=null;
}catch(IOException?ex)?{
System.err.println("Error?while?decoding?BASE64:?"+?ex.toString());
}
returndecodedBytes;
}
privatestaticvoiddecode(String?s,?OutputStream?os)throwsIOException?{
inti?=0;
intlen?=?s.length();
while(true)?{
while(i?<?len?&&?s.charAt(i)?<='?')
i++;
if(i?==?len)
break;
inttri?=?(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加密程序,源代碼如下:
//
//??DES3Util.h
//??lx100-gz
//
//??Copyright?2012http://blog.csdn.net/lyq8479.?All?rights?reserved.
//
#import?
@interface?DES3Util?:?NSObject?{
}
//?加密方法
+?(NSString*)encrypt:(NSString*)plainText;
//?解密方法
+?(NSString*)decrypt:(NSString*)encryptText;
@end
[plain]view plaincopy
//
//??DES3Util.m
//??lx100-gz
//
//??Created?by??柳峰?on?12-9-17.
//??Copyright?2012http://blog.csdn.net/lyq8479.?All?rights?reserved.
//
#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個平臺調用同一套加密程序呢?
感謝柳峰技術博客:http://blog.csdn.net/lyq8479/article/details/8062867