【问题标题】:Asymmetric encryption using PHP使用 PHP 的非对称加密
【发布时间】:2012-08-08 00:15:21
【问题描述】:

我有一个问题让我发疯。

我创建了一对钥匙在做:

$res = openssl_pkey_new(array('private_key_bits' => 2048));

/* Extract the private key from $res to $privKey */
openssl_pkey_export($res, $privKey);

/* Extract the public key from $res to $pubKey */
$pubKey = openssl_pkey_get_details($res);
$pubKey = $pubKey["key"];

使用此代码,我有 $pubKey$privKey

我可以正确加密/解密,但我对解密有很大的疑问。

目前我正在加密数据:

openssl_public_encrypt($data, $encrypted, $pubKey);

它正确加密了我的数据,但阅读 PHP 文档后,我发现:

http://php.net/manual/en/function.openssl-public-decrypt.php

我可以使用 PUBLIC KEY 解密数据吗?为什么??

我知道公钥对加密数据有用,但只有私钥的所有者才能解密数据。

如果我可以使用公钥解密数据,让知道公钥的用户轻松解密消息。

有人可以向我解释一下吗?我正在寻找一种使用两个密钥的方法,第一个用于加密,第二个(仅第二个)用于解密。

谢谢

【问题讨论】:

  • 您可以使用任一密钥进行加密。您可以尝试使用任一密钥解密,但只有其中一个会成功。无论使用哪一个加密,只有相反的才能成功解密。在某些情况下,您使用私钥加密并使用公钥解密 - 例如,作为您有权访问私钥的证明。
  • 您提到的文档没有返回解密的消息。它返回私钥的所有者是否加密了消息。为了解密消息,您需要私钥。

标签: php openssl public-key-encryption


【解决方案1】:

在非对称公钥/私钥加密中通常:

  1. Bob 生成了他的公钥/私钥对
  2. Bob 分享了他的公钥
  3. 爱丽丝用鲍勃的公钥加密一些消息
  4. 她发送消息
  5. 只有 Bob 可以使用他的私钥解密。

现在我们可以使用 openssl 库来学习基本的密码学。请注意,以下代码不适用于生产软件,仅用于学习非对称加密的基础知识。

使用该方法和以下代码,Alice 可以成功地向 Bob 发送消息

/**  BOB CODE  **/
$key = openssl_pkey_new(array('private_key_bits' => 2048));

$bob_key = openssl_pkey_get_details($key);
$bob_public_key = $bob_key['key'];

这是您代码中的基本基础架构,现在是 Bob 执行的代码。 Bob 生成密钥对并发送给 Alice,在真实环境中必须有公钥共享机制。

当 Alice 获得 Bob 的公钥后,她用这个密钥加密她的消息:

/** ALICE CODE **/
$alice_msg = "Hi Bob, im sending you a private message";
openssl_public_encrypt($alice_msg, $pvt_msg, $bob_public_key);

终于 Bob 收到消息并解密

/**  BOB CODE **/
openssl_private_decrypt( $pvt_msg, $bob_received_msg, $key);
print $bob_received_msg;

推荐的生产加密库

如果您的目标是安全的生产系统,请使用 libsodium。有了它,您可以加密消息...

// Generating your encryption key
$key = \Sodium\randombytes_buf(\Sodium\CRYPTO_SECRETBOX_KEYBYTES);

// Using your key to encrypt information
$nonce = \Sodium\randombytes_buf(\Sodium\CRYPTO_SECRETBOX_NONCEBYTES);
$ciphertext = \Sodium\crypto_secretbox('test', $nonce, $key);

...解密消息...

$plaintext = \Sodium\crypto_secretbox_open($ciphertext, $nonce, $key);
if ($plaintext === false) {
    throw new Exception("Bad ciphertext");
}

...除其他外。

What is a nonce?

Check the Full manual for using it with PHP

仔细阅读,加密不是一个星期就能学会的东西。有一些注意事项。

【讨论】:

【解决方案2】:

公钥密码术的整体理念是每个“用户”都有一个“公钥”和一个“私钥”。这些密钥有 3 种主要实现方式:机密、认证和组合。 在我的回答中,我将采用“机密”技术。

每个用户都有一个他们分发的“公钥”,其他用户将使用该“公钥”来加密将发回的消息,以及一个他们只为自己保留的“私钥”,用于解密他们将收到的消息。 您用于加密消息的密钥与用于解密的密钥不同。

“机密密钥使用”示例:

Bob 拥有:Bob 私钥,Bob 公钥,Alice 公钥
Alice 拥有:Alice 私钥,Alice 公钥密钥,鲍勃公钥

Bob 想要发送消息Alice
Bob 使用 'Alice public key' 加密消息,发送它 =>
Alice 使用 'Alice private key' 来解密消息。

Alice 想要回复并向 Bob 发送消息
Alice 使用 'Bob public key' 加密消息,发送它 =>
Bob 使用“Bob 私钥”解密消息。

公钥仅用于加密消息
私钥仅用于解密使用公钥加密的消息

现在您知道“公钥”和“私钥”的基本概念是什么了,have a look at this image explaining the typical SSL communication and the use of the keys.

【讨论】:

  • 我知道非对称加密是如何工作的......正如你写给我的那样,每个用户都使用其他用户的公钥来加密消息,但只有拥有各自私钥的用户才能解密消息。这正是我需要的。我遇到的问题(怀疑)是,如果我可以用一个密钥加密/解密,为什么要两个密钥?我的重点是有一个加密密钥和一个(私人)解密......我可以使用 php 来做吗?
  • 我相信我现在明白你在寻找什么了。如果你想用私钥加密,用公钥解密,你应该在加密端使用openssl_private_encrypt(),在解密端使用openssl_public_decrypt()。我刚刚注意到您在开篇文章中使用了 openssl_public_encrypt()
  • 如果我使用私钥加密应该有人用私钥解密消息吗?我问你,因为如果我必须使用私钥,我会把它放在我的 php 脚本中......我不希望有人可以读取 .php 文件可以使用私钥(我将写入一个变量)来解密我的加密消息
  • 不,它实际上在函数名称中说明了您正在使用哪个键。 openssl_public_encrypt() => 使用公钥加密; openssl_private_encrypt() => 使用私钥加密; openssl_public_decrypt() => 使用公钥解密; openssl_private_decrypt() => 使用私钥解密;您永远无法使用用于加密的相同密钥进行解密,因此如果您使用私钥进行加密,则应始终使用公钥进行解密,依此类推。只有使用相反的键才有效。如果您使用私钥加密 - 它只能使用公钥解密。
  • 是的,但事实并非如此。在我的示例中,您可以看到我与公众加密并再次与公众解密......这很奇怪......但它给了我解密的数据......请尝试代码
【解决方案3】:

签名,一种证明私钥所有者创建加密消息的哈希。有利于 Alice 证明 Bob 给她写了一条消息(用 Alice 的公钥加密)——而不是 Joe。 Bob 使用他的私钥创建一个唯一的签名,Alice 可以使用 Bob 的公钥来确认。

:)

【讨论】:

    【解决方案4】:

    简答

    由公钥加密的消息只能由匹配的私钥解密。

    长答案

    非对称加密双向工作。

    那么为什么还有openssl_public_decrypt() 函数呢?你可能会问。正如documentation 所述,它可以解密已由私钥加密的消息。正如之前沃利提到的,这可以用于签名。

    假设 Alice 等待 Bob 的消息,而不是其他任何人的消息。所以 Bob 使用他自己的私钥来加密消息(例如使用openssl_private_encrypt())。当 Alice 收到任何消息时,她会尝试使用 Bob 的 公钥 对其进行解密。如果成功,她就知道消息来自 Bob。

    请注意,使用私钥进行加密并不安全,因为任何人(有权访问公钥的人)都可以解密消息。在实践中,您可能会结合使用这两种方法(附加使用 Bob 的私钥加密的签名,然后使用 Alice 的公钥加密整个消息)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-25
      • 2020-10-26
      • 2011-04-05
      • 2012-01-23
      • 2013-11-30
      • 2017-09-15
      • 2019-07-29
      • 1970-01-01
      相关资源
      最近更新 更多