php 如何使用公钥/私钥加密php中的数据?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4629537/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 13:45:29  来源:igfitidea点击:

How to encrypt data in php using Public/Private keys?

phpcryptographypgpphp-openssllibsodium

提问by Xeoncross

I have a small string of some data (less than 1kb) that I would like to have user agents pass to other sites when they are sent from my site. In order for the other sites to verify that I was the one that created the string I though of two options.

我有一小串数据(小于 1kb),我希望用户代理从我的站点发送时将它们传递到其他站点。为了让其他网站验证我是创建字符串的人,我想到了两个选项。

  1. The server pings me back to confirm (like paypal, openid, etc..)
  2. I use public/private keys to prove I sent the message (like PGP, DKIM, etc..)
  1. 服务器 ping 我回确认(如 paypal、openid 等)
  2. 我使用公钥/私钥来证明我发送了消息(如 PGP、DKIM 等)

I don't want to setup HMAC because that would mean I have to use custom keys for each site which would be a pain.

我不想设置 HMAC,因为这意味着我必须为每个站点使用自定义密钥,这会很痛苦。

Out of those two choices it seems that #2 would save on bandwidth which makes it seem like a better choice.

在这两个选择中,#2 似乎可以节省带宽,这使它看起来是一个更好的选择。

So how can you setup public/private key cryptography using PHP and are there any downsides?

那么如何使用 PHP 设置公钥/私钥加密,有什么缺点吗?

采纳答案by vy32

I would create S/MIME public/private keypairs using OpenSSL and then use the OpenSSL command to do the encryption & decryption. I believe that this is superior to using PGP because openssl is included with most linux operating systems and PGP isn't. OpenSSL is also standards-based and generally easier to work with, once you have the commands down.

我将使用 OpenSSL 创建 S/MIME 公钥/私钥对,然后使用 OpenSSL 命令进行加密和解密。我相信这比使用 PGP 更好,因为 openssl 包含在大多数 Linux 操作系统中,而 PGP 没有。OpenSSL 也是基于标准的,一旦您关闭命令,通常更容易使用。

I recommended against a "pure-PHP" solution (by pure-PHP I mean doing the crypto in PHP, rather than using PHP to call an existing library or a separate executable). You don't want to do bulk crypto in PHP. Too slow. And you want to use OpenSSL, because it's high performance and the security is well understood.

我建议反对“纯 PHP”解决方案(纯 PHP 我的意思是在 PHP 中进行加密,而不是使用 PHP 来调用现有库或单独的可执行文件)。您不想在 PHP 中进行批量加密。太慢了。您想使用 OpenSSL,因为它具有高性能且安全性很好理解。

Here's the magic.

这就是魔法。

To make an X.509 key:

要制作 X.509 密钥:

$subj="/C=US/ST=California/L=Remote/O=Country Govt./OU=My Dept/CN=Mr. Agent/[email protected]"
openssl req -x509 -newkey rsa:1024 -keyout mycert.key -out mycert.pem -nodes -subj $subj

That puts the private key in mycert.key and the public key in mycert.pem. The private key is not password protected.

这将私钥放在 mycert.key 中,将公钥放在 mycert.pem 中。私钥不受密码保护。

Now, to sign a message with S/MIME:

现在,要使用 S/MIME 签署消息:

openssl smime -sign -signer mycert.pem -inkey mycert.key <input >output

To encrypt a message with S/MIME:

使用 S/MIME 加密邮件:

openssl smime -encrypt -recip yourcert.pem <input >output

To decrypt a message with S/MIME:

使用 S/MIME 解密邮件:

openssl smime -decrypt -inkey mycert.key -certfile mycert.pem <input >output

I also have some demos on using OpenSSL from the C language bindings, but not from PHP.

我也有一些关于从 C 语言绑定使用 OpenSSL 的演示,但不是来自 PHP。

回答by Eborbob

Creating a private and public key pair using the PHP Openssl functions:

使用 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"];

You can then encrypt and decrypt using the private and public keys like this:

然后,您可以使用私钥和公钥进行加密和解密,如下所示:

// 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";

回答by Scott Arciszewski

Rule 1: Don't implement it yourself, use a library.

规则 1:不要自己实现,使用库。

Which library? Here are my recommended PHP public-key cryptography libraries:

哪个图书馆?以下是我推荐的 PHP 公钥加密库

  1. Halite, depends on libsodium (but emphasizes simplicity and ease-of-use in addition to security).
  2. libsodium, from PECL
  3. EasyRSA, which implements secure public-key encryption and public-key signatures using RSA in the most secure modes (NOT PKCS1v1.5, ever!)
  4. phpseclib, which EasyRSA piggybacks off of.
  1. 岩盐,取决于libsodium(但强调简单和易于使用的,除了安全性)。
  2. ,来自 PECL
  3. EasyRSA,它在最安全的模式下使用 RSA 实现安全的公钥加密和公钥签名(永远不是 PKCS1v1.5!)
  4. phpseclib,EasyRSA 搭载了它。

In general, you'll want libsodium if security is your goal. Whether or not you use Halite is a matter of taste.

一般来说,如果安全是你的目标,你会想要 libsodium。您是否使用 Halite 是一个品味问题。

回答by Eugene Mayevski 'Callback

PGP is a good option - it is implemented properly and completely (i.e. you have little room for security mistakes with PGP). I think this SO questionwill help you with interfacing with GnuPG. The question is whether and how the other sites will verify your signature. You need to either conform to their verification mechanism requirements or provide your own module that those sites will use for verification.

PGP 是一个不错的选择 - 它得到了正确和完整的实现(即,您几乎没有空间使用 PGP 出现安全错误)。我认为这个 SO 问题将帮助您与 GnuPG 交互。问题是其他站点是否以及如何验证您的签名。您需要符合他们的验证机制要求或提供您自己的模块,这些网站将用于验证。

Also it's possible that you can use OAuth or OpenID to identify users on those other sites, but I am not an expert in these technologies.

您也可以使用 OAuth 或 OpenID 来识别其他站点上的用户,但我不是这些技术的专家。

回答by GlynRob

I've written an example of encrypting and decrypting with openSSL in PHP and Python

我在 PHP 和 Python 中编写了一个使用 openSSL 进行加密和解密的示例

http://glynrob.com/php/hashing-and-public-key-encryption/

http://glynrob.com/php/hashing-and-public-key-encryption/

Github source code available.

Github 源代码可用。

Dont forget that the private key needs to be available at the location of decryption for this to work.

不要忘记私钥需要在解密位置可用才能工作。