【问题标题】:How to change the passphrase of a private key using PHP's OpenSSL module?如何使用 PHP 的 OpenSSL 模块更改私钥的密码?
【发布时间】:2012-11-15 08:16:40
【问题描述】:

我正在使用 PHP 的 OpenSSL 模块进行非对称加密; openssl_pkey_new()、openssl_pkey_export() 和 openssl_pkey_get_details() 用于创建密钥对,openssl_public_encrypt 和 openssl_private_decrypt() 用于加密和解密数据。

如何更改与私钥关联的密码?这是否可以通过 OpenSSL 模块实现,还是我必须创建一个新的密钥对?这将非常不方便,并且需要服务器定期重新加密可能数千个文件。

谢谢!

【问题讨论】:

  • 我已经在 OpenSSL 邮件列表和 Freenode 的 ##PHP 频道连续几天询问过,但都无济于事。我在这里问错了问题,还是在这种情况下如果不通过 PHP 的 system() 函数直接调用 OpenSSL 就无法更改密码?
  • 您绝对没有问错了问题!这是一个很好的问题,我有点震惊没有人回答(直接,使用 PHP 的 OpenSSL 绑定)。希望我的回答能为你解惑!

标签: php encryption openssl public-key-encryption encryption-asymmetric


【解决方案1】:

使用phpseclib, a pure PHP RSA implementation

<?php
include('Crypt/RSA.php');

$rsa = new Crypt_RSA();
$rsa->setPassword('old_password');
$rsa->loadKey('...');

$rsa->setPassword('new_password');
$privatekey = $rsa->getPrivateKey();
$publickey = $rsa->getPublicKey();
?>

【讨论】:

    【解决方案2】:

    我需要为我在晚上构建的一个小项目执行此操作。

    我们知道以下创建了一个密钥对(公共/私有):

    function newPair (&$private, &$public, $passphrase=null) {
        $res = openssl_pkey_new ();
        if ($res === false) {
            throw new Exception ("Key generation failed: ".openssl_error_string ());
            return false;
        }
        // Sets private by reference
        if (openssl_pkey_export ($res, $private, $passphrase) === false) {
            throw new Exception ("Private key export failed: ".openssl_error_string ());
            return false;
        }
        // Array returns, contains "key" element.
        $public = openssl_pkey_get_details($res);
        if ($public === false) {
            throw new Exception (openssl_error_string ());
            return false;
        }
        $public = $public["key"];
        return true;
    }
    

    open_ssl_pkey_export() 具有密码短语的魔力。所以我们可以这样更改密码:

    function changePassphrase ($private, $old, $new=null) {
        $res = openssl_pkey_get_private ($private, $old);
        if ($res === false) {
            throw new Exception ("Loading private key failed: ".openssl_error_string ());
            return false;
        }
        if (openssl_pkey_export ($res, $result, $new) === false) {
            throw new Exception ("Passphrase change failed: ".openssl_error_string ());
            return false;
        }
        return $result;
    }
    

    我希望你能按照我们在这里所做的...! (显然,抛出异常完全是可选的......我刚刚从我的代码库中逐字提取了代码。)

    changePassphrase() 将私钥作为 字符串 以及当前和新的密码短语。我们使用 openssl_pkey_get_private() 来检索私钥的句柄,并使用旧密码将其解锁。

    (值得注意的是,密码短语实际上是用来加密私钥的,这听起来可能有点双荷兰语![正在加密加密密钥...?!] openssl_pkey_get_private() 如果无法解释密钥 - 即如果密码错误,并且私钥解密为无效值。有意义吗?)

    使用旧密码解锁私钥后,我们获取 OpenSSL 密钥句柄并将其传递给 openssl_pkey_export() - 就像我们在首先创建它之后所做的那样(通过 openssl_pkey_new())提供新密码 .. . 和嘿-presto。

    我希望我的代码示例读起来干净利落,我尝试以一种易于理解和遵循的方式编写它,没有不必要的“压缩”和捷径。

    祝你好运!

    【讨论】:

      猜你喜欢
      • 2016-08-26
      • 2017-07-07
      • 2011-10-17
      • 2012-08-25
      • 2016-05-18
      • 1970-01-01
      • 2019-08-15
      • 1970-01-01
      相关资源
      最近更新 更多