Android、iPhone和Java三個平臺一致的加密工具

1、找到文件

下載地址:https://yunpan.cn/ckxIZwyppN3Pb (提取碼:23cd)

2、導入文件

導入文件

由于這兩個文件不不支持ARC,因此應該為GTMBase64.m 和 DES3Util.m添加編譯標記-fno-objc-arc進行局部ARC禁止。

3、加密后打印出來結果

加密文件

4、修改明文

key和gIv要和后臺保持一致

這其中遇到的最讓人糾結的要屬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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,001評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,786評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,986評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,204評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,964評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,354評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,410評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,554評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,106評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,918評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,093評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,648評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,342評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,755評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,009評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,839評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,107評論 2 375

推薦閱讀更多精彩內容