简进祥==iOS 3DES加密解密
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);