Связи между входными и шифротекст длиной в AES
недавно начав использовать криптографию в моем приложении, я озадачен отношением между длиной входного текста и зашифрованным текстом, который он приводит. Перед применением криптографии было легко определить размер столбца базы данных. Теперь, однако, размер столбца изменяется незначительно.
два вопроса:
- правильно ли я предполагаю, что это связано с заполнением моего ввода, чтобы он соответствовал требованиям шифра?
- есть ли способ чтобы точно предсказать максимальную длину зашифрованного текста на основе максимальной длины входного сигнала?
и для бонусных очков: должен ли я хранить зашифрованный base64-кодированный в varchar или хранить его как необработанные байты и хранить их в varbinary? Существуют ли риски, связанные с хранением байтов в моей базе данных (я использую параметризованные запросы, поэтому теоретически случайное нарушение экранирования не должно быть проблемой) ?
ТИА!
Дополнение: В шифр, который я использую, это AES / Rijndael-256 - это отношение варьируется между доступными алгоритмами?
3 ответов
отношение зависит от обивка и сцепление режимы, которые вы используете, и размер блока алгоритма (если это блочный шифр).
некоторые алгоритмы шифрования поточных шифров которые шифруют данные "бит за битом"(или "байт за байтом"). Большинство из них производят зависящий от ключа поток псевдослучайных байтов, а шифрование выполняется XORing этого потока с данными (дешифрование идентично). С шифром потока, зашифрованный длина равна простой длине данных.
другие алгоритмы шифрования блочные шифры. Блочный шифр, номинально, шифрует один блок данных фиксированной длины. AES-блочный шифр со 128-битными блоками (16 байт). Обратите внимание, что AES-256 также использует 128-битные блоки; "256" - это длина ключа, а не длина блока. The режиме цепочки о том, как данные должны быть разделены на несколько таких блоков (это нелегко сделать безопасно, но 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 (Первоначальной Стоимости). Каждое сообщение имеет свой ИЖ, и не два сообщения, зашифрованные тем же ключом будет использовать тот же ИЖ. Некоторые режимы имеют дополнительные требования, в частности, для CBC и CTR, то в IV должны быть выбраны случайным образом с помощью криптостойкого генератора псевдослучайных чисел. IV-не секрет, но должен быть известен дешифровщику. Поскольку каждое сообщение получает свой собственный IV, часто необходимо кодировать IV вместе с зашифрованным сообщением. С CBC или CTR IV имеет длину n, Так, для АЭС, это лишние 16 байт. Я не знаю, что делает mcrypt с IV, но, криптографически говоря, IV необходимо управлять в какой-то момент.
Что касается Base64, он хорош для передачи двоичных данных через текстовые носители, но это не должно быть необходимо для правильного база данных. Кроме того, Base64 увеличивает данные примерно на 33%, поэтому его не следует применять вслепую. Я думаю, вам лучше избегать Base64 здесь.
насколько я понимаю, в блочных режимах (cbc, ecb) выходная длина будет округлена до размера блока, возвращаемого mcrypt_enc_get_block_size. Кроме того, вам нужно сохранить IV вместе с данными, поэтому размер будет округлен strlen(data) + mcrypt_enc_get_iv_size().
Что касается кодировки base64, я бы не беспокоился (но обязательно используйте шестнадцатеричную кодировку при сбросе вашей БД).
для блочного шифра AES CBC с заполнением PKCS#5,
#define BLOCKSIZE 16
size_t CipherTextLen = (PlainTxtLen / BLOCKSIZE + 1) * BLOCKSIZE;
это не учитывает вектор инициализации