我有一小段数据(小于 1kb),我想让用户代理在从我的站点发送它们时将它们传递给其他站点。为了让其他站点验证我是创建字符串的人,我想到了两个选项。
- 服务器回复我确认(如 paypal、openid 等)
- 我使用公钥/私钥来证明我发送了消息(如 PGP、DKIM 等)
我不想设置 HMAC,因为这意味着我必须为每个站点使用自定义密钥,这会很痛苦。
在这两个选择中,#2 似乎可以节省带宽,这使它看起来是一个更好的选择。
那么如何使用 PHP 设置公钥/私钥加密,有什么缺点吗?
我有一小段数据(小于 1kb),我想让用户代理在从我的站点发送它们时将它们传递给其他站点。为了让其他站点验证我是创建字符串的人,我想到了两个选项。
我不想设置 HMAC,因为这意味着我必须为每个站点使用自定义密钥,这会很痛苦。
在这两个选择中,#2 似乎可以节省带宽,这使它看起来是一个更好的选择。
那么如何使用 PHP 设置公钥/私钥加密,有什么缺点吗?
使用 PHP Openssl 函数创建私钥和公钥对:
// Configuration settings for the key
$config = array(
"digest_alg" => "sha512",
"private_key_bits" => 4096,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
);
// Create the private and public key
$res = openssl_pkey_new($config);
// Extract the private key into $private_key
openssl_pkey_export($res, $private_key);
// Extract the public key into $public_key
$public_key = openssl_pkey_get_details($res);
$public_key = $public_key["key"];
然后,您可以像这样使用私钥和公钥进行加密和解密:
// Something to encrypt
$text = 'This is the text to encrypt';
echo "This is the original text: $text\n\n";
// Encrypt using the public key
openssl_public_encrypt($text, $encrypted, $public_key);
$encrypted_hex = bin2hex($encrypted);
echo "This is the encrypted text: $encrypted_hex\n\n";
// Decrypt the data using the private key
openssl_private_decrypt($encrypted, $decrypted, $private_key);
echo "This is the decrypted text: $decrypted\n\n";
我将使用 OpenSSL 创建 S/MIME 公钥/私钥对,然后使用 OpenSSL 命令进行加密和解密。我相信这比使用 PGP 更好,因为大多数 linux 操作系统都包含 openssl 而 PGP 没有。OpenSSL 也是基于标准的,并且通常更易于使用,一旦您完成了命令。
我建议不要使用“纯 PHP”解决方案(纯 PHP 是指在 PHP 中进行加密,而不是使用 PHP 调用现有库或单独的可执行文件)。您不想在 PHP 中进行批量加密。太慢了。你想使用 OpenSSL,因为它的高性能和安全性很好理解。
这就是魔法。
要制作 X.509 密钥:
$subj="/C=US/ST=California/L=Remote/O=Country Govt./OU=My Dept/CN=Mr. Agent/emailAddress=agent@investiations.com"
openssl req -x509 -newkey rsa:1024 -keyout mycert.key -out mycert.pem -nodes -subj $subj
这会将私钥放在 mycert.key 中,将公钥放在 mycert.pem 中。私钥不受密码保护。
现在,要使用 S/MIME 签署消息:
openssl smime -sign -signer mycert.pem -inkey mycert.key <input >output
使用 S/MIME 加密邮件:
openssl smime -encrypt -recip yourcert.pem <input >output
要使用 S/MIME 解密消息:
openssl smime -decrypt -inkey mycert.key -certfile mycert.pem <input >output
我也有一些关于从 C 语言绑定中使用 OpenSSL 的演示,但不是从 PHP 中。
规则 1:不要自己实现,使用库。
哪个图书馆?这是我推荐的 PHP 公钥密码库:
一般来说,如果安全是您的目标,您将需要 libsodium。您是否使用 Halite 是一个品味问题。
PGP 是一个不错的选择——它被正确且完整地实现(即,您几乎没有使用 PGP 出现安全错误的空间)。我认为这个 SO question将帮助您与 GnuPG 交互。问题是其他网站是否以及如何验证您的签名。您需要遵守他们的验证机制要求,或者提供您自己的模块,这些站点将用于验证。
您也可以使用 OAuth 或 OpenID 来识别其他网站上的用户,但我不是这些技术的专家。