Уникальность вектора инициализации - PullRequest
2 голосов
/ 28 октября 2009

Лучше всего использовать уникальные ivs, но что уникально? Это уникально для каждой записи? или абсолютно уникальный (уникальный для каждого поля тоже)?

Если это для каждого поля, это звучит ужасно сложно, как вы управляете хранением такого большого количества iv, если у вас есть 60 полей в каждой записи.

Ответы [ 3 ]

5 голосов
/ 28 октября 2009

Еще раз, приложение C NIST pub 800-38 может быть полезным. Например, согласно этому Вы можете создать IV для режима CBC, просто зашифровав уникальный одноразовый номер с помощью своего ключа шифрования. Еще проще, если бы вы использовали OFB, тогда IV просто должен быть уникальным.


Существует некоторая путаница относительно того, каковы реальные требования для хороших IV в режиме CBC. Поэтому я считаю полезным кратко остановиться на некоторых причинах этих требований.

Давайте начнем с рассмотрения, почему ИВ даже необходимы. IV рандомизируют шифротекст. Если одно и то же сообщение дважды шифруется одним и тем же ключом (но разными IV), то шифротексты различны. Злоумышленник, которому дано два (одинаково длинных) шифротекста, не сможет определить, зашифрованы ли два шифротекста одним и тем же открытым текстом или двумя разными открытыми текстами. Это свойство обычно называется зашифрованный текст неразличимым . Очевидно, что это важное свойство для шифрования баз данных, где зашифрованы многие короткие сообщения.

Далее, давайте посмотрим, что может пойти не так, если IV предсказуемы. Давайте для примера возьмем Предложение Эриксона:

«Вы можете сделать что-то умное, например, сгенерировать одно случайное значение в каждой записи и использовать хеш имени поля и случайного значения для создания IV для этого поля».

Это небезопасно. Для простоты предположим, что у пользователя Алиса есть запись, в которой есть существует только два возможных значения m1 или m2 для поля F. Пусть Ra будет случайным значением, которое использовалось для шифрования записи Алисы. Тогда зашифрованный текст для поля F будет

E K (хеш (F || Ra) xor m).

Случайный Ra также сохраняется в записи, так как в противном случае было бы невозможно расшифровать. Злоумышленник Ева, который хотел бы узнать значение записи Алисы, может сделать следующее: во-первых, она находит существующую запись, в которую она может добавить выбранное ею значение. Пусть Re будет случайным значением, используемым для этой записи, и пусть F 'будет полем, для которого Ева может представить свое собственное значение v. Поскольку запись уже существует, можно предсказать IV для поля F', т.е. это

хеш (F '|| Re).

Ева может использовать это, выбрав ее значение v как

v = hash (F '|| Re) xor hash (F || Ra) xor m1,

разрешить базе данных зашифровать это значение, равное

E K (хэш (F || Ra) xor m1)

и затем сравните результат с записью Алисы. Если два результата совпадают, то она знает, что m1 было значением, сохраненным в записи Алисы, иначе это будет m2. Вы можете найти варианты этой атаки, выполнив поиск «блочно-адаптивная атака с выбранным открытым текстом» (например, эта статья ). Есть даже вариант, который работал против TLS.

Атака может быть предотвращена. Возможно, зашифровав случайное число перед использованием, поместив его в запись, получив IV, зашифровав результат. Но опять же, возможно, самое простое, что предлагает NIST. Создайте уникальный одноразовый номер для каждого поля, которое вы шифруете (это может быть просто счетчик), зашифруйте одноразовый номер с помощью вашего ключа шифрования и используйте результат как IV.

Также обратите внимание, что вышеуказанная атака является выбранной атакой открытым текстом. Еще более опасные атаки возможны, если у злоумышленника есть возможность делать выбранные атаки с шифрованным текстом, то есть, если он может изменить вашу базу данных. Так как я не знаю, как защищены ваши базы данных, трудно предъявлять какие-либо претензии.

5 голосов
/ 28 октября 2009

Я начал отвечать некоторое время назад, но потерпел крах, потеряв то, что вставил. То, что я сказал, было следующим:

Это зависит ...

Ключевым моментом является то, что если вы когда-либо повторно используете IV, вы открываете себя для криптографических атак, которые легче выполнять, чем те, когда вы каждый раз используете разные IV. Таким образом, для каждой последовательности, где вам нужно снова начать шифрование, вам нужен новый уникальный IV.

Вам также нужно поискать криптографических режимов - в Википедии есть отличная иллюстрация того, почему вы не должны использовать ECB. Режим CTR может быть очень полезным.

Если вы шифруете каждую запись отдельно, то вам нужно создать и записать один IV для записи. Если вы шифруете каждое поле отдельно, то вам нужно создать и записать один IV для каждого поля. Хранение IV может стать значительным дополнительным расходом, особенно если вы используете шифрование на уровне поля.

Однако вы должны решить, нужна ли вам гибкость шифрования на уровне поля. Вы можете - это маловероятно, но могут быть преимущества использования одного ключа, но разных IV для разных областей. OTOH, я сильно подозреваю, что это излишне, не говоря уже о том, чтобы напрягать ваш генератор IV (криптографический генератор случайных чисел).

Если вы можете позволить себе выполнять шифрование на уровне страницы, а не на уровне строк (при условии, что строки меньше, чем страница), вы можете воспользоваться одним IV на страницу.


Эриксон писал:

Вы можете сделать что-то умное, например, сгенерировать одно случайное значение в каждой записи и использовать хэш имени поля и случайного значения, чтобы получить IV для этого поля.

Тем не менее, я думаю, что лучшим подходом является сохранение структуры в поле, которая собирает идентификатор алгоритма, необходимые параметры (например, IV) для этого параметра и зашифрованный текст. Это может быть сохранено в виде небольшого двоичного пакета или закодировано в некоторый текст, такой как Base-85 или Base-64.

И Крис прокомментировал:

Я действительно использую режим CBC. Я думал об алгоритме 1: многие, поэтому я могу хранить только 1 IV на запись. Но сейчас я рассматриваю твою идею хранения IV с зашифрованным текстом. Не могли бы вы дать мне еще несколько советов: я использую PHP + MySQL, и многие поля являются либо varchar, либо текстовыми. У меня нет большого опыта работы с двоичным файлом в базе данных, я думал, что двоичный файл недружествен к базе данных, поэтому я всегда использую base64_encoded при хранении двоичного файла (например, IV).

К которому я бы добавил:

  • IBM DB2 LUW и Informix Dynamic Server оба используют закодированную схему Base-64 для символьного вывода своих функций ENCRYPT_AES () и связанных с ними функций, сохраняя схему шифрования, IV и другую информацию, а также зашифрованные данные.

  • Я думаю, вы должны внимательно посмотреть на режим CTR - как я уже говорил. Вы можете создать 64-битный IV из, скажем, 48-битных случайных данных плюс 16-битный счетчик. Вы можете использовать счетчик в качестве индекса в записи (вероятно, в 16-байтовых чанках - один криптоблок для AES).

  • Я не знаком с тем, как MySQL хранит данные на уровне диска. Однако вполне возможно зашифровать всю запись, включая представление значений NULL (отсутствие).

  • Если вы используете один IV для записи, но используете отдельное шифрование CBC для каждого поля, тогда каждое поле должно быть дополнено до 16 байтов, и вы определенно предаетесь «повторному использованию IV». Я думаю, что это криптографически необоснованно. Вам было бы гораздо лучше использовать один IV для всей записи и одну единицу заполнения для режима записи и CBC или без заполнения и режима CTR (поскольку CTR не требует заполнения - одно из его достоинств; другое заключается в том, что вы только используйте режим шифрования шифра как для шифрования, так и для дешифрования данных).

2 голосов
/ 28 октября 2009

Требования к уникальности IV зависят от «режима», в котором используется шифр.

Для CBC IV должен быть непредсказуемым для данного сообщения.

Для CTR IV должен быть уникальным, точка.

Для ЕЦБ, конечно, нет IV. Если поле короткое, случайный идентификатор, который умещается в одном блоке, вы можете безопасно использовать ECB.

Я думаю, что хорошим подходом является сохранение структуры в поле, которая собирает идентификатор алгоритма, необходимые параметры (например, IV) для этого алгоритма и шифротекст. Это может быть сохранено в виде небольшого двоичного пакета или закодировано в некоторый текст, такой как Base-85 или Base-64.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...