3DES是三重?cái)?shù)據(jù)加密算法塊密碼的通稱留拾,聽到名字就知道與DES加密有關(guān)稿壁,簡(jiǎn)單的理解為用DES加密三次辩尊,通過增加DES的密鑰長(zhǎng)度來(lái)避免暴力破解赎婚。
3DES算法是指使用雙長(zhǎng)度(16字節(jié))[密鑰](http://baike.baidu.com/view/934.htm)K=(KL||KR)將8字節(jié)明文[數(shù)據(jù)塊](http://baike.baidu.com/view/702806.htm)進(jìn)行3次DES加密/解密只锻。
3DES的密鑰是8個(gè)字節(jié)玖像,但實(shí)際上只有7個(gè)用上,也就是56位炬藤。
3DES是用3個(gè)或2個(gè)des密鑰加密一串明文御铃,最少112位最多168位。也就是14~21個(gè)字母或數(shù)字符號(hào)沈矿。
設(shè)Ek()和Dk()分別代表DES算法的加密和解密過程,k代表DES算法使用的密鑰咬腋,M代表明文羹膳,C代表密文,則3DES算法的過程可表示為:
加密:C = Ek3(Dk2(Ek1(M))) 即對(duì)明文數(shù)據(jù)進(jìn)行根竿,加密 --> 解密 --> 加密的過程陵像,最后得到密文數(shù)據(jù)
解密:M = Dk1(Ek2(Dk3(C))) 即對(duì)密文數(shù)據(jù)進(jìn)行,解密 --> 加密 --> 解密的過程寇壳,最后得到明文數(shù)據(jù)
這里可以K1=K3醒颖,但不能K1=K2=K3(如果相等的話就成了DES算法了)
3DES(K1=K3),可以是3DES-CBC壳炎,也可以是3DES-ECB泞歉,3DES-CBC整個(gè)算法的流程和DES-CBC一樣,但是在原來(lái)的加密或者解密處增加了異或運(yùn)算的步驟匿辩,使用的**密鑰是16字節(jié)長(zhǎng)度的密鑰**腰耙,將密鑰分成左8字節(jié)和右8字節(jié)的兩部分,即k1=左8字節(jié)铲球,k2=右8字節(jié)挺庞,然后進(jìn)行加密運(yùn)算和解密運(yùn)算。
3DES(K1≠K2≠K3)稼病,和3DES-CBC的流程完全一樣选侨,**只是使用的密鑰是24字節(jié)的**掖鱼,但在每個(gè)加密解密加密時(shí)候用的密鑰不一樣,將密鑰分為3段8字節(jié)的密鑰分別為密鑰1援制、密鑰2锨用、密鑰3,在3DES加密時(shí)對(duì)加密解密加密依次使用密鑰1隘谣、密鑰2增拥、密鑰3,在3DES解密時(shí)對(duì)解密加密解密依次使用密鑰3寻歧、密鑰2掌栅、密鑰1。
由于DES加解密算法是每8個(gè)字節(jié)作為一個(gè)加解密數(shù)據(jù)塊码泛,因此在實(shí)現(xiàn)該算法時(shí)猾封,需要對(duì)數(shù)據(jù)進(jìn)行分塊和補(bǔ)位(即最后不足8字節(jié)時(shí),要補(bǔ)足8字節(jié))
ECB模式:將待處理的數(shù)據(jù)分成若干塊噪珊,每塊的長(zhǎng)度都為8字節(jié)晌缘。然后對(duì)每塊進(jìn)行加密或解密,最后將他們連接在一起便是最終的結(jié)果痢站。每一塊的數(shù)據(jù)互不干擾磷箕。
CBC模式:也需要將待處理的數(shù)據(jù)分塊,但是每一塊數(shù)據(jù)在加密或者解密之前都要與前一塊的結(jié)果做一次異或操作阵难,因此該模式需要定義一個(gè)特殊的8字節(jié)Key岳枷,用于和第一塊數(shù)據(jù)做異或操作。這個(gè)特殊的Key就是通常說的初始化向量呜叫。在代碼中書寫時(shí)需要配置iv參數(shù)空繁,注意iv參數(shù)是對(duì)應(yīng)CBC模式的。這樣一來(lái)朱庆,每一塊數(shù)據(jù)都是有聯(lián)系的盛泡,這是與ECB模式不同的一點(diǎn)。
需要注意的是
iOS 的加密pkcs7padding那塊和安卓的不一致
一行代碼實(shí)現(xiàn)3DES加密解密需要用到寫的 JKEncrypt https://github.com/jukai9316/JKEncrypt娱颊。
下面先解析以下3DES的實(shí)現(xiàn)傲诵,然后再說,如何使用JKEncrypt维蒙。****
注意點(diǎn):填充方式不一樣
在與后臺(tái)交互的過程中掰吕,由于java 里面用的是PKCS5Padding,而iOS只有kCCOptionPKCS7Padding颅痊,所以用kCCOptionPKCS7Padding | kCCOptionECBMode 相當(dāng)于PKCS5Padding殖熟。
以下是3DES 256 在iOS開發(fā)中的實(shí)現(xiàn):
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>
#import <Security/Security.h>
#import "GTMBase64.h"
//密匙 key
#define gkey @"Kyle_Chu"
//偏移量
#define gIv @"jukai"
//密匙 key
#define gkey @"Kyle_Chu"
//偏移量
#define gIv @"jukai"
//字符串解密
-(NSString*)doDecEncryptStr:(NSString *)encryptStr{
NSData *encryptData = [GTMBase64 decodeData:[encryptStr 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|kCCOptionECBMode,
vkey,
kCCKeySize3DES,
vinitVec,
vplainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
NSString *result = [[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr
length:(NSUInteger)movedBytes] encoding:NSUTF8StringEncoding];
return result;
}
十六進(jìn)制的實(shí)現(xiàn)省略了,可以閱讀JKEncrypt.m
JKEncrypt的使用:
//1斑响、設(shè)置您需要的密匙菱属、偏移量
//密匙 key
#define gkey @"Kyle_Chu"
//偏移量
#define gIv @"jukai"
// @"kyle_jukai" 是測(cè)試字符串钳榨,換成您需要加密的內(nèi)容即可
JKEncrypt * en = [[JKEncrypt alloc]init];
//加密
NSString * encryptStr = [en doEncryptStr: @"kyle_jukai"];
NSString * encryptHex = [en doEncryptHex: @"kyle_jukai"];
NSLog(@"字符串加密:%@",encryptStr);
NSLog(@"十六進(jìn)制加密:%@",encryptHex);
//解密
NSString *decEncryptStr = [en doDecEncryptStr:encryptStr];
NSString *decEncryptHex = [en doEncryptHex:encryptHex];
NSLog(@"字符串解密:%@",decEncryptStr);
NSLog(@"字符串解密:%@",decEncryptHex);