关于CBC for ios 加密要记
倒腾了接近半天,资料找了无数,最后是通过查看Android项目中的加密工具类,才弄明白,在这过程中掌握了一些知识点。比如:
问题1:关于PKCS7Padding和PKCS5Padding
iOS中AES加密算法采用的填充是PKCS7Padding,而java不支持PKCS7Padding,只支持PKCS5Padding。在IOS中, kCCOptionPKCS7Padding ,其实单单这个参数就是告诉了函数运用CBC加密模式;kCCOptionPKCS7Padding|kCCOptionECBMode,就表示运用了ECB加密模式;在DES中加密数据包单位长度是8字节,在8字节的情况下PKCS7Padding 等价与 PKCS5Padding。
PKCS7Padding跟PKCS5Padding的区别就在于数据填充方式,PKCS7Padding是缺几个字节就补几个字节的0,而PKCS5Padding是缺几个字节就补充几个字节的几,好比缺6个字节,就补充6个字节的6 。
问题2:关于Des和3DES
Cipher cipher=Cipher.getInstance("DESede/CBC/PKCS5Padding");
a.DESede加密算法的名称,如DESede实际上是3-DES。这一段还可以放其它的对称加密算法,如Blowfish等
b.CBC是分组加密的模式,除了CBC和ECB之外,还可以是NONE/CFB/QFB等。最常用的就是CBC和ECB了。DES采用分组加密的方式,将明文按8字节(64位)分组分别加密。如果每个组独立处理,则是ECB。CBC的处理方式是先用初始向量IV对第一组加密,再用第一组的密文作为密钥对第二组加密,然后依次完成整个加密操作。如果明文中有两个分组的内容相同,ECB会得到完全一样的密文,但CBC则不会。
c.最后一个分组的填充方式。大部分情况下,明文并非刚好64位的倍数。对于最后一个分组,如果长度小于64位,则需要用数据填充至64位。PKCS5Padding是常用的填充方式,如果没有指定,默认的方式就是它。
ps:补充一点,虽然DES的有效密钥长度是56位,但要求密钥长度是64位(8字节)。3DES则要求24字节。
问题3:关于中文加密不正确
通过代码1加密的密文与Android段加密的不一致(汉字),所以改段代码有些不正确,请用代码2
最后附上一段玩具代码1:
1 NSString *cryptionKey = @"xxxxxxxxxxx"; 2 NSString *ciphertext = nil; 3 const char *textBytes = [_pwdTextField.text UTF8String]; 4 NSUInteger dataLength = [_pwdTextField.text length]; 5 unsigned char buffer[1024]; 6 memset(buffer, 0, sizeof(char)); 7 const void *iv = (const void *)[aString UTF8String]; 8 size_t numBytesEncrypted = 0; 9 CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithm3DES, 10 kCCOptionPKCS7Padding, 11 [cryptionKey UTF8String], kCCKeySize3DES, 12 iv, 13 textBytes, dataLength, 14 buffer, 1024, 15 &numBytesEncrypted); 16 if (cryptStatus == kCCSuccess) { 17 NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted]; 18 NSString *astring1 = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 19 NSLog(@"dds:%@", astring1); 20 ciphertext = [[NSString alloc] initWithData:[GTMBase64 encodeData:data] encoding:NSUTF8StringEncoding]; 21 22 }
代码2:
1 NSString *cryptionKey = @"xxxxxxxxxxxx"; 2 NSData *adata = [[NSData alloc] initWithBytes:ivKey length:8]; 3 NSString *iV = [[NSString alloc] initWithData:adata encoding:NSUTF8StringEncoding]; 4 5 6 NSData* data = [_userNameTextField.text dataUsingEncoding:NSUTF8StringEncoding]; 7 size_t plainTextBufferSize = [data length]; 8 const void *vplainText = (const void *)[data bytes]; 9 10 CCCryptorStatus ccStatus; 11 uint8_t *bufferPtr = NULL; 12 size_t bufferPtrSize = 0; 13 size_t movedBytes = 0; 14 15 bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1); 16 bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t)); 17 memset((void *)bufferPtr, 0x0, bufferPtrSize); 18 19 const void *vkey = (const void *) [cryptionKey UTF8String]; 20 const void *vinitVec = (const void *) [iV UTF8String]; 21 22 ccStatus = CCCrypt(kCCEncrypt, 23 kCCAlgorithm3DES, 24 kCCOptionPKCS7Padding, 25 vkey, 26 kCCKeySize3DES, 27 vinitVec, 28 vplainText, 29 plainTextBufferSize, 30 (void *)bufferPtr, 31 bufferPtrSize, 32 &movedBytes); 33 34 NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes]; 35 NSString *result = [GTMBase64 stringByEncodingData:myData];
资料链接:
http://blog.csdn.net/u010184533/article/details/38975871
http://www.cocoachina.com/bbs/read.php?tid-273195-page-3.html
http://www.cnblogs.com/qkhh/p/4683626.html
http://www.programering.com/a/MzN1cjNwATQ.html
其他资料:
http://www.jianshu.com/p/98610bdc9bd6
https://my.oschina.net/tinglanrmb32/blog/351021