Intereting Posts
Продукты Woocommerce, показывающие сообщение «Нет на складе», когда на самом деле нет на складе Создать изображение из URL-адреса Любой тип файла Получить идентификатор пользователя при входе пользователя в систему с использованием Username & Password завершать длинные слова или длинные символы, игнорируя теги html Вычтите одну секунду из заданного времени Как анализировать json-ответ от CURL Проблемы с перенаправлением на контактную форму Измените uri модуля без переименования класса в PyroCMS Как настроить WAMP (localhost) для отправки электронной почты с помощью Gmail? Использование глобальной переменной PHP внутри файла yml Создание индекса с помощью Elasticsearch 5.0 вызывает исключение Bad Request Почему «mysql_connect» обескуражен и каковы альтернативы? MySQL – вычисление полей «на лету» и хранение вычисленных данных PHP (Apache) безмолвно преобразует HTTP 429 и другие в 500 Предупреждение: Memcached :: getMulti (): не удалось выполнить инициализацию значения, без поддержки

Связь между длиной ввода и длиной зашифрованного текста в AES

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

Два вопроса:

  1. Правильно ли я предполагаю, что это связано с заполнением моего ввода, чтобы оно соответствовало требованиям шифрования?
  2. Есть ли способ точно предсказать максимальную длину зашифрованного текста на основе максимальной длины ввода?

И для бонусных очков: должен ли я хранить шифрованный текст base64-кодированный в varchar или хранить его как необработанные байты и хранить их в varbinary? Существуют ли риски, связанные с хранением байтов в моей базе данных (я использую параметризованные запросы, поэтому теоретически случайное нарушение выхода не должно быть проблемой)?

ТИА!

Дополнительно: Шифр, который я использую, это AES / Rijndael-256. Разница между этими алгоритмами варьируется?

Отношение зависит от используемого режима заполнения и цепочек , а также от размера блока алгоритма (если это блок-шифр).

Некоторые алгоритмы шифрования – это потоковые шифры, которые шифруют данные «бит за битом» (или «byte by byte»). Большинство из них генерируют зависящий от ключа поток псевдослучайных байтов, а шифрование выполняется посредством XORing этого потока с данными (дешифрование идентично). С помощью шифрования потока зашифрованная длина равна простой длине данных.

Другие алгоритмы шифрования – это блок-шифры . Блочный шифр, номинально, шифрует один блок данных фиксированной длины. AES – это блок-шифр с 128-битными блоками (16 байт). Обратите внимание, что AES-256 также использует 128-битные блоки; «256» – это длина ключа, а не длина блока. Режим цепочки связан с тем, как данные должны быть разделены на несколько таких блоков (это непросто сделать безопасно, но режим CBC в порядке). В зависимости от режима цепочки, данные могут потребовать некоторого заполнения , т. Е. Добавлено несколько дополнительных байтов в конце, чтобы длина была подходящей для режима цепочки. Заполнение должно быть таким, чтобы его можно было однозначно удалить при расшифровке.

В режиме CBC входные данные должны иметь длину, кратную длине блока, поэтому принято добавлять дополнение PKCS # 5: если длина блока равна n , то добавляется не менее 1 байт, самое большее n , так что общий размер кратен n , а последние добавленные байты (возможно, все из них) имеют числовое значение k, где k – количество добавленных байтов. После дешифрования достаточно посмотреть на последний дешифрованный байт, чтобы восстановить k и, следовательно, знать, сколько удаляемых байтов должно быть в конечном счете удалено.

Следовательно, с режимом CBC и AES, предполагая заполнение PKCS # 5, если входные данные имеют длину d, тогда зашифрованная длина равна (d + 16) & ~15 . Здесь я использую C-образную нотацию; Простыми словами, длина между d + 1 и d + 16 и кратная 16.

Существует режим, называемый CTR (как «счетчик»), в котором блок-шифр шифрует последовательные значения счетчика, давая поток псевдослучайных байтов. Это фактически превращает блок-шифр в потоковый шифр, и, таким образом, сообщение длины d зашифровывается в d байтов.

Предупреждение: обо всех системах шифрования (включая потоковые шифры) и режимах требуется дополнительное значение, называемое IV (начальное значение). Каждое сообщение должно иметь свой IV, и никакие два сообщения, зашифрованные одним и тем же ключом, не должны использовать один и тот же IV. В некоторых режимах есть дополнительные требования; в частности, как для CBC, так и для CTR, IV выбирается случайным образом и равномерно с криптографически сильным генератором псевдослучайных чисел. IV не является секретом, но должен быть известен decrypter. Поскольку каждое сообщение получает свой собственный IV, часто необходимо кодировать IV вместе с зашифрованным сообщением. С CBC или CTR IV имеет длину n , поэтому для AES это дополнительные 16 байт. Я не знаю, что делает mcrypt с IV, но, криптографически говоря, IV должен управляться в какой-то момент.

Что касается Base64, это полезно для передачи двоичных данных поверх текстовых носителей, но это не обязательно для надлежащей базы данных. Кроме того, Base64 увеличивает данные примерно на 33%, поэтому его нельзя применять вслепую. Я думаю, вам лучше избегать Base64 здесь.

По моему мнению, в выходной части блока (cbc, ecb) длина вывода будет округлена до размера блока, как указано mcrypt_enc_get_block_size. Кроме того, вам нужно хранить IV вместе с данными, поэтому размер будет округленным strlen (data) + mcrypt_enc_get_iv_size ().

Что касается кодировки base64, я бы не стал беспокоиться (но обязательно используйте шестнадцатеричное кодирование при сбросе вашего db).

Для блочного шифрования AES CBC с дополнением PKCS # 5,

 #define BLOCKSIZE 16 size_t CipherTextLen = (PlainTxtLen / BLOCKSIZE + 1) * BLOCKSIZE; 

Это не учитывает вектор инициализации