Ответ 1
Безопасность CTR требует, чтобы вы никогда не повторно использовали IV для двух сообщений с одним и тем же ключом. На самом деле он еще более строг: режим 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 через обман:
-
Генерировать 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
).
Предупреждение: во всем вышеизложенном, я ничего не говорю о том, помогает ли шифрование файлов cookie в предоставлении любых характеристик безопасности, которые вы пытаетесь достичь. Обычно, когда требуется шифрование, вам действительно нужны как шифрование, так и целостность, а затем вы должны использовать режим комбинированного шифрования и целостности. Поиск GCM и CCM, Более того, шифрование файлов cookie в основном хорош для одной цели, что позволяет избежать затрат на хранение на стороне сервера немного пользовательских данных. Если вы хотите зашифровать файл cookie для чего-то другого, например. для проверки подлинности действительного пользователя, тогда вы делаете это неправильно: шифрование для этого не подходит.