3DES(或稱為Triple DES)是三重資料加密演算法(TDEA,Triple Data Encryption Algorithm)塊密碼的通稱。它相當於是對每個資料區塊應用三次DES密碼編譯演算法。由於電腦運算能力的增強,原版DES密碼的密鑰長度變得容易被暴力破解;3DES即是設計用來提供一種相對簡單的方法,即通過增加DES的密鑰長度來避免類似的攻擊,而不是設計一種全新的塊密碼演算法。
3DES又稱Triple DES,是DES密碼編譯演算法的一種模式,它使用3條56位的金鑰組資料進行三次加密。資料加密標準(DES)是美國的一種由來已久的加密標準,它使用對稱金鑰密碼編譯法,並於1981年被ANSI組織規範為ANSI X.3.92。DES使用56位密鑰和密碼塊的方法,而在密碼塊的方法中,文本被分成64位大小的文字區塊然後再進行加密。比起最初的DES,3DES更為安全。
一行代碼實現3DES加密解密需要用到寫的 JKEncrypt https://github.com/jukai9316/JKEncrypt。
下面先解析以下3DES的實現,然後再說,如何使用JKEncrypt。
注意點:填充方式不一樣
在與後台互動的過程中,由於java 裡面用的是PKCS5Padding,而iOS只有kCCOptionPKCS7Padding,所以用kCCOptionPKCS7Padding | kCCOptionECBMode 相當於PKCS5Padding。
以下是3DES 256 在iOS開發中的實現:
#import <CommonCrypto/CommonDigest.h> #import <CommonCrypto/CommonCryptor.h>#import <Security/Security.h>#import "GTMBase64.h" //密匙 key#define gkey @"Kyle_Chu"//位移量#define gIv @"jukai" //字串加密-(NSString *)doEncryptStr:(NSString *)originalStr{ //把string 轉NSData NSData* data = [originalStr dataUsingEncoding:NSUTF8StringEncoding]; //length 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]; //配置CCCrypt ccStatus = CCCrypt(kCCEncrypt, kCCAlgorithm3DES, //3DES kCCOptionECBMode|kCCOptionPKCS7Padding, //設定模式 vkey, //key kCCKeySize3DES, vinitVec, //位移量,這裡不用,設定為nil;不用的話,必須為nil,不可以為@“” vplainText, plainTextBufferSize, (void *)bufferPtr, bufferPtrSize, &movedBytes); NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes]; NSString *result = [GTMBase64 stringByEncodingData:myData]; return result;} //字串解密-(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;}
十六進位的實現省略了,可以閱讀JKEncrypt.m
JKEncrypt的使用:
//1、設定您需要的密匙、位移量//密匙 key#define gkey @"Kyle_Chu"//位移量#define gIv @"jukai" // @"kyle_jukai" 是測試字串,換成您需要加密的內容即可JKEncrypt * en = [[JKEncrypt alloc]init];//加密NSString * encryptStr = [en doEncryptStr: @"kyle_jukai"];NSString * encryptHex = [en doEncryptHex: @"kyle_jukai"];NSLog(@"字串加密:%@",encryptStr);NSLog(@"十六進位加密:%@",encryptHex);//解密NSString *decEncryptStr = [en doDecEncryptStr:encryptStr];NSString *decEncryptHex = [en doEncryptHex:encryptHex];NSLog(@"字串解密:%@",decEncryptStr);NSLog(@"字串解密:%@",decEncryptHex);
ps:iOS DES加密與3DES加密
最近項目中遇到了加解密的問題,然後翻閱了相關資料,成功搞定。 現在將這些知識點總結一下,一是為了以後複習,二是為了給大家提供參考。
1. 先來說說DES操作,定義我這裡就不敘述了,網上一堆一堆的。接下來說一下使用時應該注意的幾點。 首先,大家要分清Key(密鑰),Data(待操作資料)跟Mode(加密模式)。其中Key必須為8位元組(64位),Data需要是8位元組(64位)的倍數,這裡需要注意了,如果Data不是8位元組的倍數,那麼我們需要進行資料填充,資料填充使用的演算法不一定相同。Mode貌似有許多種,這裡只簡單的說一下ECB跟CBC模式。
ECB模式:將待處理的資料分成若干塊,每塊的長度都為8位元組(64位),與Key長度相同。然後對每塊進行加密或解密,最後將他們串連在一起便是最終的結果。每一塊的資料互不干擾。
CBC模式:也需要將待處理的資料分塊,但是每一塊資料在加密或者解密之前都要與前一塊的結果做一次異或操作,因此該模式需要定義一個特殊的8位元組Key,用於和第一塊資料做異或操作。這個特殊的Key就是通常說的初始化向量。在代碼中書寫時需要配置iv參數,注意iv參數是對應CBC模式的。這樣一來,每一塊資料都是有聯絡的,這是與ECB模式不同的一點。
2. 再來說說3DES操作,也就是進行3次DES操作。設Ek()和Dk()分別代表DES演算法的加密和解密過程,k代表DES演算法使用的密鑰,P代表明文,C代表密文,則3DES演算法的過程可表示為:
C = Ek3(Dk2(Ek1(P)))
P = Dk1(Ek2(Dk3(C)))
3DES同樣有ECB跟CBC模式,同上面講的一樣。這裡需要注意一下Key的長度,應該是24位。比如我們已知的Key是16位的,那麼我們需要將其分為2段,每一段都是8位,則k1=左8位, k2=右8位,k3=左8位,也就是 k1=k3,但不能k1=k2=k3,因為如果每段使用的Key都相同,就回到DES演算法了。