Я уже прочитал обсуждение.Следует ли нам подписывать, а затем шифровать, или шифровать, а затем подписывать?и бумагаНеисправная подпись и шифрование в S/MIME, PKCS#7, MOSS, PEM, PGP и XML. Мой вопрос касается того, что делает gpg. Это было немного сложно определить эмпирически, поскольку вывод:
gpg --encrypt --sign <filename>
Меняется каждый раз, когда я его запускаю. (Почему?)
@Jens объяснил, что отчасти причина в том, что включена временная метка. Есть ли способ это убрать? Я не вижу опции gpg.
Поскольку порядок опций, по-видимому, не имеет значения, и поскольку я не могу использовать опцию --detach-sign
(в любом случае создается только один файл вывода), я подозреваю, что вывод представляет собой:
\begin{equation}
E_r (msg\ \| \ E_s (\#msg))
\end{equation}
где $E_r$
— шифрование с открытым ключом получателя, $E_s$
— шифрование с закрытым ключом отправителя, $msg$
— сообщение, $\#msg$
— хэш сообщения и $\|$
— конкатенация.т.е.это будет «подписать-сообщение-затем-зашифровать». Это правильно?
Или вместо этого:
\begin{equation}
E_r (msg) \ \| \ E_s (\#msg)
\end{equation}
Другими словами, это «зашифровать-а затем-подписать-используя-открытый-текст»? Я предполагаю, что это такнет«зашифровать-затем-подписать-шифротекст», ($E_r (msg) \ \| \ E_s (\# E_r (msg))$)
поскольку это противоречило бы разделу 1.2 в упомянутой выше статье.
@Jens объяснил, что это действительно «подписать-сообщение-затем-зашифровать». Так как же нам «зашифровать-затем-подписать-используя-открытый-текст», получив на выходе один файл openpgp, а не два файла, один с зашифрованными данными, а другой с подписью?
Кроме того, я читал статьи и руководства — где, кроме самого кода, мне искать эту информацию?
@Jens предложил запустить:
echo 'foo' | gpg --recipient [key-id] --encrypt --sign | gpg --list-packets
Я запустил его, зашифровав для себя, и нашел вывод ниже. Может ли кто-нибудь объяснить, что он нам говорит?
[...]
gpg: okay, we are the anonymous recipient.
:encrypted data packet:
length: unknown
mdc_method: 2
gpg: encrypted with RSA key, ID 00000000
:compressed packet: algo=2
:onepass_sig packet: keyid C6701618143AFA1E
version 3, sigclass 0x00, digest 10, pubkey 1, last=1
:literal data packet:
mode b (62), created 1443494042, name="",
raw data: 4 bytes
:signature packet: algo 1, keyid C6701618143AFA1E
version 4, created 1443494042, md5len 0, sigclass 0x00
digest algo 10, begin of digest d7 3a
hashed subpkt 2 len 4 (sig created 2015-09-29)
subpkt 16 len 8 (issuer key ID C6701618143AFA1E)
data: [4095 bits]
решение1
Это было немного сложно определить эмпирически, поскольку вывод:
gpg --encrypt --sign <filename>
меняется каждый раз, когда я его запускаю. (Почему?)
Этому есть две причины:
- Симметричное шифрование в OpenPGP использует случайный вектор инициализации (или, скорее, похожую конструкцию с фиксированным вектором инициализации).
- Включена метка времени создания подписи.
Подпись и шифрование или шифрование и подпись — что делает gpg?
GnuPG сначала подписывает сообщение, а затем шифрует его. Вы можете проверить это с помощью gpg --list-packets
:
echo 'foo' | gpg --recipient [key-id] --encrypt --sign | gpg --list-packets
Который сначала подписывает, а затем шифрует сообщение, на что указывает порядок пакетов.
Насколько я понимаюRFC 4880, OpenPGPОднако определены оба порядка: сообщения OpenPGP могут быть подписями, зашифрованными, сжатыми и буквальными данными, при этом подписи применяются к сообщениям OpenPGP, а расшифрованные сообщения также должны формировать сообщения OpenPGP.