如何使用 PHP 解密对称加密的 OpenPGP 消息?

How to decrypt a symmetrically encrypted OpenPGP message using PHP?

我有一条 OpenPGP 消息,它看起来像在文件中给我的:

-----BEGIN PGP MESSAGE-----
Version: GnuPG v1.4.9 (MingW32)

jA0EAgMCtCzaGHIQXY9g0sBnAeDOQ9GuVA/uICuP+7Z2dnjNCLgRN0J/TzJs1qcW
aJYBTkH5KQCClCxjwTYbHZCox1sENfIS+KxpCKJQqAX3SNEFm0ORNE6RNwEgb1Zj
uOdIw8auxUsjmQKFLAcZIPKjBjyJqSQVfmEoteVn1n+pwm8RdIZevCHwLF2URStB
nBVuycaxcaxcaxcxccxcxacqweqweqwe123fsMqQPaTusOBGpEQrWC9jArtvYEUpY
aNF6BfQ0y2CYrZrmzRoQnmtnVu10PagEuWmVxCucyhVwlthVgN0iBog9jhjliQkc
rrDTupqB4IimMEjElGUHtkuvrCQ0jQnOHEAJmmefMDH0NkYKGd5Ngt21I5ge5tob
/uBjHKMxjNgg1nWfg6Lz4jqoKe/EweuEeg==
=+N9N
-----END PGP MESSAGE-----

我想是给了一个 15 个字符的密码来解密它。但我真的不知道使用 PHP 解密文件。我看一下 PHP's GnuPG manual page 并在 gnugpg_decrypt() 示例下给出了以下代码:

$res = gnupg_init();
gnupg_adddecryptkey($res,"8660281B6051D071D94B5B230549F9DC851566DC","test");
$plain = gnupg_decrypt($res,$encrypted_text);
echo $plain;

所以看看这个函数 gnupg_adddecryptkey,它提到我需要指纹。那到底是什么?我在哪里可以得到它?

指纹是根据 public 密钥和一些元数据(如密钥创建时间)计算的哈希和。通过 gnupg_import 作为 fingerprint 属性导入密钥后也会返回。

这是针对 public/private 密钥加密的,您似乎没有使用它:使用密码加密时,您省略了 public/private 密钥加密部分并直接使用对称加密消息,带有从您的密码派生的会话密钥(有时也称为密码块或对称密钥)。

PHP 的 GnuPG 模块不支持对称加密。没有执行对称解密的函数,这个限制在module's source documentation:

中也有描述

This class provides an object oriented interface to GNU Privacy Guard (GPG).

Though GPG can support symmetric-key cryptography, this class is intended only to facilitate public-key cryptography.

您必须通过调用 gpg 手动执行解密。一个示例命令行是

gpg --symmetric --decrypt [file]

(或者,您也可以通过 STDIN 提供输入)。要交出密码,请查看 GnuPG 的 --passphrase... 选项:

--passphrase-fd n

Read the passphrase from file descriptor n. Only the first line will be read from file descriptor n. If you use 0 for n, the passphrase will be read from STDIN. This can only be used if only one passphrase is supplied.

--passphrase-file file

Read the passphrase from file file. Only the first line will be read from file file. This can only be used if only one passphrase is supplied. Obviously, a passphrase stored in a file is of questionable security if other users can read this file. Don't use this option if you can avoid it.

--passphrase string

Use string as the passphrase. This can only be used if only one passphrase is supplied. Obviously, this is of very questionable security on a multi-user system. Don't use this option if you can avoid it.

请注意,一台计算机的所有其他用户都可以读取所有其他用户的命令行参数,因此尤其是对于共享主机平台,--passphrase 绝对不行。

这个答案不仅与 PHP 兼容,而且与一般的 GnuGPG 兼容。总结 Jens Erat 的回答并为遇到此问题的任何其他人添加加密步骤,这是一个解决方案,假设存在一个名为 passwords.txt:

的文件
// encrypt
gpg --output passwords.gpg --symmetric passwords.txt
// decrypt
gpg —decrypt  passwords.gpg