【问题标题】:Filling memory with random bytes - C/Objective-C用随机字节填充内存 - C/Objective-C
【发布时间】:2011-08-07 11:45:16
【问题描述】:

我在 Objective-C (AES256) 中使用 CommonCrypto 进行加密,我想提供一个 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:我只提供了 crypto/Objective-C 背景,所以你知道我需要这个。我认为这不会影响任何事情。 kCCBlockSizeAES128 = 16 (90% 确定:)

编辑:

好吧!在一些调试之后,我很高兴地宣布,我在加密和解密方面遇到的问题是由于我现在已经解决的程序的另一部分中的一个错误。所以我现在需要弄清楚的是如何用随机字节填充 iv。一些选项:

  • 使用 malloc(),它返回垃圾而不是随机字节 -> 可能不安全 (?)
  • 使用 arc4random_buf(),这正是我想要的,只是它只适用于 10.7+,而我的 mac 是 10.6.6(另外我想支持 10.6)
  • 还有什么我没有考虑过的……?

编辑 2:

好吧!在用一些测试数据(全零、全一等)和更多调试后,我很高兴地宣布 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; } 毫无意义。
  • @Mat 我这样做是因为如果您为 crpypto 提供 NULL,它将始终创建一个全零的 IV。当我无法创建 IV 时,我让 crypto 创建一个归零的 IV。否则我想要一个随机 IV。
  • 你的帖子很模糊:“似乎失败了”?确保它失败了。此外,无论 IV 的内容如何,​​该加密功能都应该起作用 - 可能不安全,但会起作用。所以你的问题可能在其他地方。请更详细地描述 什么 不起作用以及它是如何失败的。 (if 块内的语句只有在!iv 为真时才会运行,只有在iv == null... 时才会发生。)
  • @Mat 好吧,我说它似乎失败了,因为我加密文件没有问题,但是当我解密它时,它的信息与原始文件不同。你是对的,这很模糊。我会继续调试。如果我找到什么我会告诉你的。关于 if (!iv) {...},我明白你现在的意思了 :)
  • @Mat 我已经更新了我的问题,你能再检查一下吗?

标签: objective-c c memory random fill


【解决方案1】:

您可以使用arc4random_buf 用随机数据填充缓冲区:

#include <stdlib.h>
#include <stdint.h>

uint8_t iv[kCCBlockSizeAES128];
arc4random_buf(&iv, kCCBlockSizeAES128);

此外,malloc 返回的内存块(与任何未初始化的内存一样)被 垃圾 填充。你不应该假设它会被任何东西填充,尤其是在密码学上有用的随机数。

【讨论】:

  • 编译器找不到函数arc4random_buf,即使有import语句。是 arc4random_addrandom() 还是类似的东西?
  • 确保您正在针对 Mac OS X 10.7 或 iOS 4.3(或更高版本)SDK 进行编译。
  • 嗯,我正在使用 Mac OS 10.6 进行编译...但是 arc4random_addrandom() 可以吗?
  • 这可能是一个愚蠢的问题,为什么你将 &iv 传递给 arc4random_buf 而不仅仅是 iv?我认为 iv 已经是一个指针,我们只需要将随机数据放在 iv 指向的位置......
  • 不是&iv包含指针值的地址吗?我认为你应该通过 iv 而不是 &iv
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-31
  • 1970-01-01
  • 1970-01-01
  • 2015-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多