我正在使用CommonCrypto对Objective-C中的加密进行AES256位加密,我想为更安全的加密提供一个IV(初始化向量)。目前我的做法如下:
const void* iv = malloc(kCCBlockSizeAES128);
// EDIT:
//if (!iv) {
// iv = NULL;
//}
然后我创建了加密器对象:
CCCryptorRef cryptor;
CCCryptorStatus cryptStatus = CCCryptorCreate(operation, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES256,
iv,
&cryptor);
问题在于这种加密方式似乎失败了(伤心脸...)。我的意思是:它加密时没有明显的问题,但解密后的数据与原始数据不同。我认为这应该是可行的,因为当你使用
malloc()
分配内存时,它并不会全部写入零,而是随机的。我还尝试自己编写随机值,但我的C语言知识有限。如果有一个类似于bzero
的函数可以写入随机字节,请告诉我。
我还尝试了类似以下的操作:
char* iv = malloc(kCCBlockSizeAES128);
int i;
srand((unsigned int)time(NULL));
for (i = 0; i < kCCBlockSizeAES128; i++) {
iv[i] = (char)rand()%256;
}
哦,顺便说一下,我意识到这可能是一个非常新手的问题 :)
最后我想要的东西就像 const void* iv = malloc(kCCBlockSizeAES128)
一样,在经过一些操作后我确定它的数据是完全随机的。有什么想法吗?
PS:我只提供加密/解密和Objective-C的背景信息,所以您知道我需要这个用途。我认为这不会影响任何事情。kCCBlockSizeAES128 = 16(90%确定 :)。
编辑:
好吧!经过一些调试,我很高兴地宣布,我遇到的加密和解密问题是由于程序中另一部分中存在错误造成的,现在我已经解决了。现在我需要弄清楚的是如何填充iv随机字节。一些选项:
- 使用malloc(),它返回垃圾而不是随机字节-> 可能不安全(?)
- 使用arc4random_buf(),正是我想要的,但它仅适用于10.7+,我的Mac是10.6.6(而且我想支持10.6)
- 我没有考虑到的其他事情...? <-- 在这里帮助!
编辑2:
好吧!在用一些测试数据(全零,全一等)填充iv并更多的调试后,我不再高兴地宣布ccrypto似乎在某些条件下不起作用。我将解释如何进行:
每当我向加密提供一个为零的iv或NULL时(加密同理),它都有效。例如,在加密和解密时,这很好用:
uint8_t iv[kCCBlockSizeAES128];
int i;
for (i = 0; i < kCCBlockSizeAES128; i++) {
iv[i] = 0x0; // I know this is the same as doing: memset((void *)iv, 0x0, (size_t)sizeof(iv));
}
CCCryptorRef cryptor;
CCCryptorStatus cryptStatus = CCCryptorCreate(operation, kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
(const void *)keyPtr, kCCKeySizeAES256,
iv,
&cryptor);
但是,当我向他输入一个至少有一个字节不为零的 IV 时,加密/解密并没有出现错误,但解密后的数据并不是原始数据。例如,下面这个...
uint8_t iv[kCCBlockSizeAES128];
int i;
for (i = 0; i < kCCBlockSizeAES128; i++) {
iv[i] = 0x1;
}
或者用于完全随机数据...
uint8_t iv[kCCBlockSizeAES128];
int i;
for (i = 0; i < kCCBlockSizeAES128; i++) {
iv[i] = arc4random() % 256;
}
无法工作。 我完全不理解这个逻辑...有什么想法吗?
if (!iv) { iv = NULL; }
没有意义。 翻译:上述代码“如果iv为假值,则将其赋值为NULL”是没有实际作用的语句。 - Mat