iOS开发-AES、DES加密
2017-03-31 本文已影响465人
海0_0滨
本文主要说AES加密,而DES大同小异,揭秘也是一个属性的问题
首先,网络上关于iOSAES加密的资料与方法有很多,并且也都可以运行,但是大部分作者都是就自己项目写的代码,具体参数和可能出现坑的地方都没有说明白,也就是说,那些代码可能没有错,但就是不适用于你自己的项目。
特别说明:1. 本文是自己项目中用到后用来记录之用,也为了兴许能帮助到的同胞。如果有说的不对的地方,感谢指正;2. 以下代码是自己学习过程中,通过网络上不同大神们的代码结合所成;3. 以下言论需要斟酌后使用,出错不负责,帮你解决问题也不收礼
先上代码
/**
* 加密
*
* @param plainText 明文
* @param key 密钥
* @param iv 向量
*
* @return 密文
*/
+ (NSString *)AES256Encrypt:(NSString *)plainText key:(NSString *)key iv:(NSString *)iv {
char keyPtr[kCCKeySizeAES256+1];
memset(keyPtr, 0, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
char ivPtr[kCCBlockSizeAES128 + 1];
memset(ivPtr, 0, sizeof(ivPtr));
[iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
size_t bufferSize = [data length] + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
keyPtr,
[key length],
ivPtr,
[data bytes],
[data length],
buffer,
bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
return [resultData base64EncodedStringWithOptions:0];
}
free(buffer);
return nil;
}
需要注意的地方有几个:
- CCCrypt 第一个参数:kCCEncrypt:加密 ;kCCDecrypt:解密
- CCCrypt 第二个参数:区分AES加密与DES加密
- key(密钥)的长度,
char keyPtr[kCCKeySizeAES256+1];
需要注意此处后台给你的key的长度,AES的key长度kCCKeySizeAES128 = 16, kCCKeySizeAES192 = 24, kCCKeySizeAES256 = 32,
- 向量的长度,
char ivPtr[kCCBlockSizeAES128 + 1];
一般就是16位,我自己认为没有再多的了 - 最后一个非常要注意的点:iOS中填充模式没有[kCCOptionPKCS5Padding][1]模式,而如果后台跟安卓又都是kCCOptionPKCS5Padding的话,那iOS就可以在CCCrypt参数中用kCCOptionPKCS7Padding | kCCOptionECBMode(不写的话默认为CBC模式)来代替。以下纯属个人猜想🐶为什么加了这个东西,结果出来就跟kCCOptionPKCS5Padding的一样:因为IV向量默认是16个0,而kCCOptionPKCS7Padding的填充模式又是不足补0,但是ECB加密模式是不需要向量的,所以在kCCOptionPKCS7Padding的基础上加了kCCOptionECBMode就跟kCCOptionPKCS5Padding的是缺几个字节就补充几个字节的几模式结果一样了😜
- 如果不写kCCOptionECBMode,使用了默认的CBC模式,并且没有固定向量IV的话,每次的加密结果都会是不一样的,因为,CBC时需要向量的,所以每次会生成一个随机的向量,所以每次加密结果都不一样。
- 在出现错误时从以下几个方面进行检查
- key与IV长度问题
- 填充模式问题kCCOptionPKCS5Padding,kCCOptionPKCS7Padding
- 很多时候,后台的同事也不明白AES加密的具体情况,他们可能也只是从网络上找了一些方法来加密,所以,不用太指望别人跟你说他们模式等东西。最好的办法就是,给后台一个明文,让他们用他们的模式生成一个秘文,然后确定好KEY与IV之后,在自己的程序中修改参数最终确定是那种模式(当然,如果后台给你,把AES加密的各种模式都跟你说了,最好)
-
PKCS7Padding跟PKCS5Padding的区别就在于数据填充方式,PKCS7Padding是缺几个字节就补几个字节的0,而PKCS5Padding是缺几个字节就补充几个字节的几,好比缺6个字节,就补充6个字节的6 ↩