如何使用公共/私钥在PHP中加密数据?
-
08-10-2019 - |
题
我有一小串数据(小于1KB),我想让用户代理从我的网站发送到其他站点。为了使其他站点验证我是一个创建两个选项的字符串i的站点。
- 服务器将我拨回确认(例如PayPal,OpenID等)。
- 我使用公共/私钥证明我发送了消息(例如PGP,DKIM等)。
我不想设置HMAC,因为那意味着我必须为每个站点使用自定义键,这将很痛苦。
在这两个选择中,似乎#2可以节省带宽,这使它看起来像是一个更好的选择。
那么,如何使用PHP设置公共/私钥密码学,并且是否有缺点?
解决方案
我将使用OpenSSL创建S/MIME公共/私人按键,然后使用OpenSSL命令进行加密和解密。我认为这比使用PGP优于使用PGP,因为大多数Linux操作系统都包含OpenSSL,而PGP不包括PGP。 OpenSSL也是基于标准的,一旦您将命令降低后,通常更易于使用。
我建议使用“纯PHP”解决方案(通过Pure-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。
其他提示
使用PHP OPENSL函数创建私有密钥对:
// 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";
规则1:不要自己实施,请使用库。
哪个图书馆? 这是我推荐的PHP公钥加密图书馆:
- halite, ,取决于lisbodium(但除了安全性外,还强调了简单性和易用性)。
- libsodium, ,来自pecl
- Easyrsa, ,它在最安全的模式下使用RSA(不是PKCS1V1.5,曾经!)实现安全的公钥加密和公钥签名。
- phpseclib, ,easyrsa piggy背。
通常,如果安全性是您的目标,您将需要libsodium。您是否使用halite是一种口味问题。
PGP是一个不错的选择 - 它是正确而完全实现的(即,您几乎没有PGP安全错误的空间)。我认为 这个问题 将帮助您与GNUPG接口。问题是其他站点是否以及如何验证您的签名。您需要符合其验证机制要求,或提供自己的模块,这些模块将用于验证。
另外,您可能可以使用Oauth或OpenID在其他网站上识别用户,但是我不是这些技术的专家。
我写了一个用php和python中的Openssl加密和解密的示例
http://glynrob.com/php/hashing-and-public-key-cerryptim/
GitHub源代码可用。
不要忘记,私钥需要在解密位置可用,以使其工作。