[英]How to change the passphrase of a private key using PHP's OpenSSL module?
I'm using PHP's OpenSSL module for asymmetric encryption; 我正在使用PHP的OpenSSL模块进行非对称加密; openssl_pkey_new(), openssl_pkey_export(), and openssl_pkey_get_details() to create the keypair, and openssl_public_encrypt and openssl_private_decrypt() to encrypt and decrypt data. openssl_pkey_new(),openssl_pkey_export()和openssl_pkey_get_details()用于创建密钥对,openssl_public_encrypt和openssl_private_decrypt()用于加密和解密数据。
How can I change the passphrase associated with the private key? 如何更改与私钥关联的密码? Is this possible with the OpenSSL module, or do I have to create a new keypair? 这可能是OpenSSL模块,还是我必须创建一个新的密钥对? That would be extremely inconvenient and require the server to re-encrypt potentially thousands of files on a regular Basis. 这将非常不方便,并要求服务器在常规基础上重新加密可能的数千个文件。
Thanks! 谢谢!
I've needed to do this for a little project I've been building in the evenings. 我需要为晚上建造的一个小项目做这件事。
We know the following creates a new key pair (public/private): 我们知道以下内容创建了一个新的密钥对(公共/私有):
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() does the passphrase magic. open_ssl_pkey_export()执行密码魔术。 So we can change the passphrase as so: 所以我们可以改变密码:
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;
}
I hope you can follow what we've done here ... ! 我希望你能按照我们在这里所做的一切......! (Obviously the exception throwing is purely optional ... I've just pulled the code verbatim from my codebase.) (显然异常抛出纯粹是可选的......我只是从代码库中逐字地提取代码。)
changePassphrase() takes the private key as a string , along with the current and new passphrases. changePassphrase()将私钥作为字符串 ,以及当前和新的密码。 We use openssl_pkey_get_private() to retrieve a handle to the private key, unlocking it with the old passphrase. 我们使用openssl_pkey_get_private()来检索私钥的句柄,使用旧的密码解锁它。
(It's worth noting that the passphrase is literally used to encrypt the private key, which may sound a little double-dutch! [Encrypting the encryption key ... ?!] openssl_pkey_get_private() returns FALSE if it fails to interpret the key - ie if the passphrase is wrong, and the private key decrypts to an invalid value. Make sense?) (值得注意的是,密码短语实际上用于加密私钥,这可能听起来有点双重![加密加密密钥......?!] openssl_pkey_get_private()如果无法解释密钥则返回FALSE - 即如果密码错误,私钥解密为无效值。有意义吗?)
Having unlocked the private key with the old passphrase, we take the OpenSSL key handle and pass it to openssl_pkey_export() - just like we did after creating it in the first place (via openssl_pkey_new()) providing the new passphrase ... and hey-presto. 使用旧密码解锁私钥后,我们使用OpenSSL密钥句柄并将其传递给openssl_pkey_export() - 就像我们在首先创建它(通过openssl_pkey_new())后提供新密码一样......并且嘿-presto。
I hope my code example reads cleanly, I've tried to write it in a fashion that's easy to understand and follow, without unnecessary "compression" and short-cutting. 我希望我的代码示例干净利落地阅读,我试图以一种易于理解和遵循的方式编写它,没有不必要的“压缩”和短切。
Good luck! 祝好运!
Using phpseclib, a pure PHP RSA implementation : 使用phpseclib,一个纯PHP RSA实现 :
<?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();
?>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.