在这里留下一个答案,因为网络上的许多 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 版本。