2011-01-05 7 views
24

Я хотел был бы зашифровать cookies, которые написаны webapp, и я хотел бы сохранить размер куки-файлов до минимума, следовательно, я выбрал AES/CTR/NoPadding.Как выбрать подходящий IV (вектор инициализации) для AES/CTR/NoPadding?

Что вы рекомендовали бы использовать в качестве IV, который является достаточно случайным и по-прежнему сохраняет приложение без гражданства. Я знаю, что могу просто создать случайный IV и добавить его в сообщение, но это увеличит размер файла cookie.

Кроме того, какой рекомендуемый размер IV для 128-разрядной AES?

Как еще все это делают? Существуют ли какие-либо «проверенные и истинные» способы? Я не хочу изобретать велосипед.

+1

Почему вам должно быть интересно, если размер файла cookie сделан на несколько байт больше? –

ответ

42

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

Простой способ сделать это - использовать криптографически безопасный генератор случайных чисел и создать новый 16-байтовый случайный IV для каждого сообщения. Я подчеркиваю «криптографически безопасную», потому что это важно; базового генератора случайных чисел недостаточно. С Java используйте java.util.SecureRandom. С Win32 позвоните по номеру CryptGenRandom(). При случайном выборе пространство возможного 128-битного IV достаточно велико, что столкновения крайне маловероятны. Фактически, именно поэтому AES использует 128-битные блоки (таким образом, подразумевая 128-бит IV).

Сущность, которая расшифровывает сообщение, должна знать IV, поэтому вам необходимо сохранить его вместе с зашифрованным сообщением. Это дополнительные 16 байт. Я понимаю, что это накладные расходы - это то, чего вы хотите избежать, хотя 16 байтов не так много для файла cookie. Эффективная максимальная длина файла cookie зависит от веб-браузера, но 4000 символов работают повсюду. 16-байтовый IV, когда он кодируется в символах (например, Base64), будет использовать около 22 символов, т. Е. Значительно меньше 1% от вашего максимального размера файла cookie: может быть, вы можете себе это позволить?

Теперь мы можем получить фанк и попытаться уменьшить длину IV через обмане:

  • Сформировать капельницу с хэш-функции: на стороне сервера, использовать счетчик, который начинается с 0 и увеличивается каждый раз, когда требуется новый IV. Чтобы получить IV, вы используете хэш-счетчик с подходящей хеш-функцией, например. SHA-256, и вы сохраняете первые 16 байтов хэш-значения. «Свойства рандомизации» хэш-функции будут достаточными, чтобы сделать IV достаточно случайным в отношении требований CTR. Для этого требуется криптографически безопасная хеш-функция, поэтому SHA-256 (избегайте MD5). Затем вам нужно сохранить значение счетчика в файле cookie, а счетчик будет короче 16 байт (например, если у вас не более 4 миллиардов клиентов, счетчик будет соответствовать 4 байтам). Однако есть скрытые затраты: сервер (я полагаю, сервер выполняет шифрование в вашей системе) должен убедиться, что он никогда не использует значение счетчика, поэтому он должен хранить «текущий счетчик» где-то таким образом, который сохраняется сервер перезагружается, а также не прерывается, если вы масштабируете до нескольких фронтов. Кажется, это не так просто.

  • Используйте внешнее уникальное значение: Возможно, файл cookie может быть частью контекста, который обеспечивает достаточное количество данных для генерации значения, которое будет уникальным для каждого шифрования. Например, если запрос также содержит (в ясном) «идентификатор пользователя», вы можете использовать идентификатор пользователя в качестве источника IV. Настройка похожа на приведенную выше: вы получаете все эти данные, загружаете их в SHA-256, а первые 16 байтов вывода SHA-256 - это IV, который вам нужен. Это работает только в том случае, если эти данные не изменяются для данного зашифрованного сообщения и если они действительно уникальны. Это редкое явление: например, «идентификатор пользователя» хорош для этого только в том случае, если никогда не требуется повторно шифровать новое сообщение для одного и того же пользователя, и если никогда не существует возможности повторного использования идентификатора пользователя (например, старый пользователь завершает работу, появляется новый пользователь и выбирает теперь бесплатный идентификатор пользователя).

Использование случайного 16-байтового IV, производимую с использованием криптографически безопасного PRNG до сих пор является «безопасным» способом, и один я рекомендую. Если вы найдете место в файле cookie, то это означает, что вы приближаетесь к пределу 4 kB, после чего вы можете использовать сжатие (по данным до, после шифрования сжатие очень маловероятно) , Используйте zlib (на Java вы можете получить доступ к zlib через java.util.zip).

Предупреждение: всего вышеперечисленного, я не говорю, ничего о действительно ли шифрование печенье помочь в обеспечении характеристик любой безопасности, которые вы пытаетесь достичь. Обычно, когда требуется шифрование, вам действительно нужны как шифрование, так и целостность, а затем вы должны использовать режим комбинированного шифрования и целостности. Поиск GCM и CCM. Более того, шифрование файлов cookie в основном хорош для одной цели, что позволяет избежать затрат на хранение на стороне сервера немного пользовательских данных. Если вы хотите зашифровать файл cookie для чего-то другого, например. до аутентифицировать действительного пользователя, то вы делаете это неправильно: шифрование для этого не является правильным инструментом.

+0

Как взять хэш данных как IV? Это все еще нужно передавать с зашифрованными данными, но не требует ресурсов на стороне сервера между запросами и должно давать разные IV для разных сообщений. Или есть недостаток в этой схеме? – jochen

+1

Использование хэша данных, поскольку IV имеет два возможных недостатка: 1. Если вы дважды зашифруете одно и то же сообщение, вы получите дважды тот же зашифрованный результат, и злоумышленник может его увидеть. Это может быть или не быть проблемой в вашем конкретном контексте. 2. Публикация хеш-сообщения (как IV) позволяет злоумышленнику выполнить исчерпывающий поиск в текстовом сообщении: попытка получения сообщений открытого текста до тех пор, пока не будет найдено совпадение. Как правило, гораздо меньше возможных текстовых сообщений, чем возможные ключи. Чтобы исправить это, IV не должен быть хешем сообщения, но, скажем, MAC (с HMAC). –

+1

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

2

Если вы не делаете IV случайным (т. Е. Используете некоторую повторяющуюся группу чисел), будет легче определить ключ, если файл cookie всегда начинается с того же чистого текста.

Размер IV для AES-128 составляет 128 бит. IIRC, IV имеет тот же размер, что и блок шифрования. 128 бит - 16 байт. 32 байта, если вы храните его как шестнадцатеричную строку ASCII. Это действительно слишком много? 32 байта в этот день и возраст совсем невелик ...

4

У меня нет прямого ответа на ваш вопрос, но есть несколько вещей, которые можно добавить.

Прежде всего, шифрование файла cookie не имеет для меня смысла. Если вам нужна конфиденциальность ваших данных, вы все равно не должны хранить их в файле cookie. Если вам нужна целостность (т. Е. Невозможно изменить содержимое файла cookie), вы должны использовать хеш-ключ (HMAC, например).

Другое примечание к никогда используйте IV, который все 0 только для удобства.

IV имеют размер по размеру вашего блока. В случае AES-128 размер блока равен 128, ключ - 128 и, следовательно, IV - 128 бит.

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

редактировать:

Вы можете посмотреть на этой странице вики для получения дополнительной информации о каком режиме использовать. Однако никогда не используйте ECB, если вы не уверены, что его следует использовать. И даже тогда, проверьте с экспертом. CBC, насколько я знаю, самый безопасный (вместе с PCBC).

http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation

+2

Статический IV убивает CTR. – Drew

+0

Действительно, режим 'CTR' вообще не защищает целостность - можно перевернуть любые выбранные биты открытого текста, поэтому, если известно, что открытый текст содержит, например,' admin = 0', то преобразование его в 'admin = 1' тривиально. Если вы хотите целостность, используйте HMAC. – caf

+1

Почему бы вам CTR-режим вместо CBC? Его сложнее испортить CTR, чем с CBC. Думаю, – Henri

0

Включите большое случайное число с куки. Число 64 или 128 бит, вероятно, достаточно велико. Он должен быть достаточно большим, чтобы получить очень много дубликатов. Не забудьте поставить достаточно энтропии в это число. Не просто используйте gettime(). Если у вас есть доступ к CRNG, используйте его здесь.

Храните 256-битный мастер-ключ с вашим приложением. Используйте SHA256 для получения вашей ключевой информации. Опять же, используйте CRNG для этого.

$keyblob = sha256(concat("aeskeyid", $masterkey , $randomnumberwithcookie)) 
$aeskey = $keyblob[0..15] 
$aesiv = $keyblob[16..31] 

Вы также можете получить ключ для HMAC.

$mackeyblob = sha256(concat("hmackeyid", $masterkey , $randomnumberwithcookie)) 

В качестве альтернативы вы можете объединить вышеуказанные две операции хэша в одну с помощью SHA512.

$keyblob = sha512(concat("randomkeyid", $masterkey , $randomnumberwithcookie)) 
$aeskey = $keyblob[0..15] 
$aesiv = $keyblob[16..31] 
$hmackey = $keyblob[32..63] 
0

Можно избежать случайного IV, используя CBC и сохраняя HMAC перед сообщением. Использование случайно подобранной константы IV нормально. Но вы должны быть уверены, что все сообщения разные.

Это тот случай, когда зашифрованное сообщение всегда отличается. Лицензионный ключ с серийным номером будет соответствовать этим критериям. Файл cookie с идентификатором пользователя или идентификатором сеанса будет соответствовать ему.

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

Даже не думайте использовать CTR с постоянным IV.