Мне интересно, есть ли способ создать Cryptographic Nonce с помощью библиотек OpenSSL или Crypto++. Есть ли в этом что-то большее, чем просто генерация набора случайных байтов с использованием пулов с автозаполнением?
Сгенерировать одноразовый номер С++
Ответы (3)
Мне интересно, есть ли способ создать криптографический одноразовый номер с использованием библиотек OpenSSL или Crypto++.
Крипто++:
SecByteBlock nonce(16);
AutoSeededRandomPool prng;
prng.GenerateBlock(nonce, nonce.size());
OpenSSL:
unsigned char nonce[16];
int rc = RAND_bytes(nonce, sizeof(nonce));
unsigned long err = ERR_get_error();
if(rc != 1) {
/* RAND_bytes failed */
/* `err` is valid */
}
/* OK to proceed */
Есть ли в этом что-то большее, чем просто генерация набора случайных байтов с использованием пулов с автозаполнением?
Nonce - это в основном IV. Обычно это общедоступный параметр, такой как IV или соль.
Одноразовый номер должен быть уникальным в контексте безопасности. Вам также может понадобиться одноразовый номер, чтобы быть непредсказуемым.
Уникальность и непредсказуемость — два разных свойства. Например, счетчик, начинающийся с 0000000000000000
, уникален, но также и предсказуем.
Когда вам нужна и уникальность, и непредсказуемость, вы можете разделить одноразовый номер на случайное значение и счетчик. Случайное значение займет 8 байтов из 16-байтового одноразового номера; в то время как счетчик займет оставшиеся 8 байтов 16-байтового одноразового номера. Затем вы используете функцию приращения, чтобы в основном выполнять i++
каждый раз, когда вам нужно значение.
Вам не нужен раскол 8-8. 12-4 работает, как и 4-12. Это зависит от приложения и количества одноразовых номеров, необходимых перед изменением ключа. Изменение ключей обычно управляется количеством байтов обычного текста.
16-0 тоже работает. В этом случае вы используете случайные значения, избегая счетчика и функции приращения. (Функция приращения в основном представляет собой каскадное добавление).
NIST SP800-38C и SP800-38D предлагает несколько способов создания одноразовых номеров. потому что CCM и GCM используют их.
Также см. Каковы требования к одноразовому номеру? на Crypto Stack Exchange.
Вам нужен уникальный номер для каждого одноразового номера. Вы можете использовать либо серийный номер, либо случайное число. Для обеспечения уникальности обычно, хотя и не обязательно, к одноразовому номеру добавляется метка времени. Либо передать временную метку как отдельное поле, либо объединить ее с одноразовым номером. Иногда также добавляется такая информация, как IP-адреса и идентификаторы процессов.
При использовании серийного номера вам не нужно беспокоиться о пропуске номеров. Это нормально. Просто убедитесь, что вы никогда не повторяетесь. Он должен быть уникальным для перезапусков вашего программного обеспечения. Это одно из мест, где может помочь добавление метки времени. Потому что время в миллисекундах + серийный номер почти наверняка уникальны при перезапусках сервера.
Для генератора псевдослучайных чисел подойдет любой. Просто убедитесь, что вы используете достаточно большое пространство, чтобы шансы получить дубликат были практически исключены. Опять же, добавление времени уменьшит вероятность того, что вы получите дубликаты, поскольку вам нужно будет получить одно и то же случайное число дважды за одну и ту же миллисекунду.
Вы можете захэшировать одноразовый номер, чтобы скрыть содержащиеся в нем данные (например, идентификатор процесса), хотя хеш будет безопасным только в том случае, если вы включите в одноразовый номер безопасное случайное число. В противном случае наблюдатель одноразового номера может угадать компоненты и подтвердить их, переделав хэш (т. е. угадать время и попробовать все возможные идентификаторы процессов).
Нет. Если одноразовый номер достаточно велик, то DRBG с автозаполнением (детерминированный генератор случайных битов — номенклатура NIST) вполне подойдет. Я бы предложил одноразовый номер около 12 байтов. Если одноразовый номер должен быть 16 байт, вы можете оставить младшие значащие биты — чаще всего крайние правые байты — равными нулю для максимальной совместимости.
Достаточно просто использовать криптографически безопасные генераторы случайных чисел, предоставляемые API, — они должны быть заполнены с использованием информации, полученной от операционной системы (возможно, среди других данных). Никогда не помешает добавить системное время к начальным данным просто для уверенности.
В качестве альтернативы вы можете использовать серийный номер, но это потребует от вас сохранения некоторого состояния, которое может быть затруднено при вызовах. Имейте в виду, что есть много ловушек, которые могут позволить часам повторяться (переход на летнее время, изменения ОС, разряженная батарея и т. д. и т. д.).
Никогда не помешает дважды проверить, что генератор случайных чисел не повторяется для достаточно большого вывода. Были проблемы только с ошибками программирования или конфигурации системы, например. когда исправление после статического анализа кода для Debian привело к тому, что генератор случайных чисел OpenSSL не был заполнен вообще.