Заполнение памяти случайными байтами - C / Objective-C - PullRequest
4 голосов
/ 07 августа 2011

Я использую CommonCrypto для шифрования в Objective-C (AES256), и я хотел бы предоставить IV (вектор инициализации) для более безопасного шифрования. В настоящее время я делаю это:

const void* iv = malloc(kCCBlockSizeAES128);
// EDIT:
//if (!iv) {
//    iv = NULL;
//}

и затем я создаю объект cryptor:

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% уверены:)

EDIT:

Allright! После некоторой отладки я с радостью сообщаю, что проблема, с которой я столкнулся при шифровании и дешифровании, была связана с ошибкой в ​​другой части моей программы, которую я сейчас решил. Теперь все, что мне нужно выяснить, - это заполнить iv случайными байтами. Некоторые варианты:

  • Используйте malloc (), которая возвращает ненужные, а не случайные байты -> потенциально небезопасно (?)
  • Используйте arc4random_buf (), это именно то, что я хочу, за исключением того, что он работает только 10.7+, а мой Mac - 10.6.6 (плюс я хочу поддерживать 10.6)
  • Что-то еще, что я не учел ...? <- помогите здесь! </strong>

РЕДАКТИРОВАТЬ 2:

Allright! После заполнения 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;
}

... не будет работать.

Я не понимаю эту логику в одиночку ... Есть идеи?

1 Ответ

10 голосов
/ 07 августа 2011

Вы можете использовать arc4random_buf для заполнения буфера случайными данными:

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

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

Кроме того, блок памяти, возвращаемый malloc (как и любая неинициализированная память), заполняется мусором . Не следует предполагать, что оно будет заполнено чем-либо , особенно бесполезными случайными числами.

...