在这里留下一个答案,因为网络上的许多PHP GnuPG的例子都是非常简陋的,希望这能给某人带来一些挫败感。
基本上,它反映了GnuPG命令行工具的工作原理。您需要导入密钥,如果它尚未在gpg的密钥环中,则需要选择收件人的密钥用于加密/解密。
gpg --import recipients-public-key.asc
gpg -r recipient --encrypt test.txt
如果你做了我所做的,并以收件人的身份传递了密钥,它就不起作用了!
目前尚不清楚GPG手册或PHP文档中的这个字段是什么,该文档将此字段称为“指纹”。使用以下命令检查 gpg 的钥匙圈中是否有新导入的密钥:
gpg --list-keys
这将输出如下内容:
pub rsa2048 2019-04-14 [SC] [expires: 2021-04-14]
0DAA2C747B1974BE9EB9E6DCF7EE249AD00A46AA
uid [ultimate] Dean Or
sub rsa2048 2019-04-14 [E] [expires: 2021-04-14]
这将为您提供UID,并在第二行上提供与每个键关联的指纹。据我所知,您可以使用UID和指纹作为收件人。
因此,要加密的 PHP 代码可能如下所示:
// Encrypt
$gpg = new gnupg();
$gpg->seterrormode(gnupg::ERROR_EXCEPTION);
// Check key ring for recipient public key, otherwise import it
$keyInfo = $gpg->keyinfo('0DAA2C747B1974BE9EB9E6DCF7EE249AD00A46AA');
if (empty($keyInfo)) {
$gpg->import('recipients-public-key.asc');
}
$gpg->addencryptkey('0DAA2C747B1974BE9EB9E6DCF7EE249AD00A46AA');
echo $gpg->encrypt('This is a test!');
然后收件人的代码将如下所示:
// Decrypt
$gpg = new gnupg();
$gpg->seterrormode(gnupg::ERROR_EXCEPTION);
// Check key ring for recipient private key, otherwise import it
$keyInfo = $gpg->keyinfo('0DAA2C747B1974BE9EB9E6DCF7EE249AD00A46AA');
if (empty($keyInfo)) {
$gpg->import('recipients-private-key.asc');
}
$gpg->adddecryptkey('0DAA2C747B1974BE9EB9E6DCF7EE249AD00A46AA', '');
echo $gpg->decrypt($encyptedMessage);
请注意,收件人的公钥和私钥的指纹是相同的。
还有一个已知问题,adddecryptkey不采用密码短语!您需要删除密码或更改 GnuPG 的版本。