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

发布于 2024-10-10 14:02:35 字数 339 浏览 13 评论 0原文

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

  1. 服务器向我发送 ping 消息以确认(如 paypal、openid 等)。
  2. 我使用公钥/私钥来证明我发送了消息(如 PGP、DKIM 等)。

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

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

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

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.

  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..)

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.

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

复古式 2024-10-17 14:02:35

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

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

// 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";
遥远的她 2024-10-17 14:02:35

我将使用 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/[email protected]"
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 中使用 OpenSSL。

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.

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.

Here's the magic.

To make an X.509 key:

$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.

Now, to sign a message with S/MIME:

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

To encrypt a message with S/MIME:

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

To decrypt a message with 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.

蓬勃野心 2024-10-17 14:02:35

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

哪个图书馆? 这是我推荐的 PHP 公共-关键密码学库

  1. Halite,依赖于libsodium(但强调简单性和易用性除了安全之外)。
  2. libsodium,来自 PECL
  3. EasyRSA,它以最安全的模式使用 RSA 实现安全的公钥加密和公钥签名(不是 PKCS1v1.5!)
  4. phpseclib,EasyRSA 搭载的。

一般来说,如果安全是您的目标,您会需要 libsodium。是否使用岩盐取决于品味。

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

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

  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.

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

安静被遗忘 2024-10-17 14:02:35

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

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

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 question will 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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文