5

Я пытаюсь создать очень маленькие зашифрованные OpenPGP файлы, которые можно встраивать в QR-коды.

Однако, по сравнению, например, с OpenSSL, GnuPG, похоже, дает очень большие результаты для простого ввода 'a':

$ echo -n a|openssl enc -aes-256-ctr|wc -c 
17
$ echo -n a|gpg --symmetric -o-|wc -c
71

Из прочтения руководства одно из отличий заключается в том, что OpenSSL по умолчанию включает только 8-байтовый заголовок и 8-байтовую соль, а GnuPG также включает в себя соль, контрольные суммы и сжатие. Если они отключены, размер файла меньше, но все еще высок:

$ echo -n a|gpg --symmetric --compress-algo none --disable-mdc --s2k-mode 0 -o-|wc -c
35

Есть ли способ еще больше оптимизировать зашифрованное сообщение OpenPGP (при этом AES будет включен)?

1 ответ1

6

Хотя двоичный формат GnuPG довольно компактен, он создан для гибкости, а не для абсолютно минимальных размеров сообщений (обычно реальное сообщение намного больше, чем несколько байтов). Минимальное "обычное" сообщение OpenPGP имеет размер 31 байт, но вы все равно можете сократить его до 26 байт с некоторыми дополнительными усилиями, что является наименьшим возможным сообщением OpenPGP v4 для однобайтового содержимого.

Рассеивание сообщения OpenPGP, подсчет байтов

Взглянув на RFC 4880, вы можете получить минимальную длину сообщения, которую вы не можете использовать ниже.

Давайте посмотрим на вывод команды, которую вы создали:

$ echo -n a|gpg --symmetric --compress-algo none --disable-mdc --s2k-mode 0 -o-|gpg --list-packets
gpg: Note: simple S2K mode (0) is strongly discouraged
    gpg: AES encrypted data
gpg: encrypted with 1 passphrase
gpg: WARNING: message was not integrity protected

Первый пакет является зашифрованным сессионным ключом пакета сеансового ключа. Он содержит копию ключа сеанса, зашифрованную парольной фразой с использованием механизма «строка-к-ключу». OpenSSL не делает этого, но вы не можете пропустить это, если не предоставите ключ сеанса вместо ключевой фразы, отдельно предоставив ключ сеанса (обсуждается ниже). Этот пакет имеет шесть байт и состоит из:

# off=0 ctb=8c tag=3 hlen=2 plen=4
:symkey enc packet: version 4, cipher 7, s2k 0, hash 10

Теперь зашифрованные пакеты данных запускаются. Это содержит:

  • 2-байтовый заголовок пакета (тег и длина)
  • Случайный префикс в 18 байт (вместо 0-байтового IV CFP OpenPGP использует случайный префикс в размере блока шифра и повторяет первые два байта; AES использует 128 бит = 16 байтов в качестве длины блока шифра)
# off=6 ctb=c9 tag=9 hlen=2 plen=26 new-ctb
:encrypted data packet:
    length: 26

OpenPGP всегда сохраняет сообщение в буквальном пакете данных, который добавляет некоторые метаданные. Отключение сжатия, по крайней мере, удаляет дополнительные заголовки сжатия. Этот пакет наконец добавляет еще 9 байтов:

  • 2-байтовый заголовок пакета (тег и длина)
  • 1-байтовый формат данных
  • Длина строки имени файла в 1 байт (значение ноль, имя файла не следует)
  • Метка времени 4 байта
  • 1 байт
# off=26 ctb=cb tag=11 hlen=2 plen=6 new-ctb
:literal data packet:
    mode b (62), created 1503680075, name="",
    raw data: 0 bytes

Подводя итог: вы не сможете сохранить еще один байт - если не пропустите вывод строки в ключ и напрямую используете ключ сеанса вместо ключевой фразы.

Пропуск функции "строка-к-ключу"

GnuPG позволяет читать и устанавливать ключ сеанса, используя --show-session-key и --override-session-key . Читая главу о создании сообщений, я был удивлен, что действительные сообщения OpenPGP вообще не требуют пакетов, определяющих шифрование сеансового ключа. GnuPG действительно поддерживает этот вид операций, но я бы не стал ставить ставку на другие реализации, так как это очень эзотерический способ использования OpenPGP.

   OpenPGP Message :- Encrypted Message | Signed Message |
                      Compressed Message | Literal Message.
   Encrypted Message :- Encrypted Data | ESK Sequence, Encrypted Data.
   Encrypted Data :- Symmetrically Encrypted Data Packet |
         Symmetrically Encrypted Integrity Protected Data Packet

Это должно сохранить 6 байтов пакета сеансового ключа с зашифрованным симметричным ключом.

Создание сообщения OpenPGP без пакета ключа сеанса с зашифрованным симметричным ключом

Я не нашел способа заставить GnuPG использовать предопределенный сеансовый ключ. Но вы можете сгенерировать симметрично зашифрованное сообщение, извлечь ключ сеанса во время дешифрования, а затем разделить сообщение.

Шифрование сообщения:

$ echo -n a|gpg --symmetric --compress-algo none --disable-mdc --s2k-mode 0 -o message.gpg

Извлечение сеансового ключа (запросит пароль):

$ gpg --show-session-key 0 --decrypt message.gpg
gpg: AES encrypted data
gpg: encrypted with 1 passphrase
gpg: session key: '7:F7FBBA6E0636F890E56FBBF3283E524C'
agpg: WARNING: message was not integrity protected

Разделите сообщение OpenPGP на отдельные пакеты:

$ gpgsplit message.gpg

Папка теперь держит четыре файла: зашифрованный message.gpg зашифрованного message симметричный ключ шифруется ключ сеанс пакет 000001-003.sym_enc и , наконец, зашифрованный пакет 000002-009.encrypted данных.

$ ls -l
total 16
-rw-r--r-- 1 jenserat jenserat  6 Aug 25 19:36 000001-003.sym_enc
-rw-r--r-- 1 jenserat jenserat 29 Aug 25 19:36 000002-009.encrypted
-rw-r--r-- 1 jenserat jenserat  1 Aug 25 19:04 message
-rw-r--r-- 1 jenserat jenserat 35 Aug 25 19:33 message.gpg

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

Расшифровка отдельного зашифрованного пакета данных

Этот шаг довольно прост:

$ gpg --override-session-key '7:F7FBBA6E0636F890E56FBBF3283E524C' --decrypt 000002-009.encrypted 
agpg: WARNING: message was not integrity protected

Не пропускайте a перед предупреждающим сообщением, которое является выходным.

Значение предупреждающих сообщений

GnuPG напечатал два предупреждающих сообщения.

gpg: Примечание: простой режим S2K (0) настоятельно не рекомендуется

Это связано с тем, что простой режим S2K делает атаки методом «грубой силы» и «словарь» по ключевой фразе дешевыми и легкими, поскольку он не использует хеширование и соль.

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

gpg: ПРЕДУПРЕЖДЕНИЕ: сообщение не защищено целостностью

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .