我在创建/使用在PHP中创建和使用的RSA密钥方面有一个问题。问题是,(公共和私人)密钥应该在不同的服务器之间交换(例如,当移动用户帐户时)。
现在,PHP的openssl库没有提供任何关于密钥创建格式的详细信息。最新文档位于http://php.net/manual/en/function.openssl-pkey-export.php只是声明它是“PEM格式”,但没有说明它是在PKCS#1还是PKCS#8中
此外,私钥PEM的标头和尾部在不同的PHP版本中有所不同,如下代码所示:
<?php
$config = array(
"digest_alg" => 'sha512',
"private_key_bits" => 4096,
"private_key_type" => OPENSSL_KEYTYPE_RSA
);
$keyPair = openssl_pkey_new($config);
$privateKey = NULL;
openssl_pkey_export($keyPair, $privateKey);
var_dump($privateKey);
$keyDetails = openssl_pkey_get_details($keyPair);
$publicKey = $keyDetails['key'];
var_dump($publicKey);
die();
?>
会输出不同的东西:
PHP v 5.4:
string(3272) "-----BEGIN PRIVATE KEY-----
MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqA//...
-----END PRIVATE KEY-----
"
string(800) "-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAO//...
-----END PUBLIC KEY-----
"
PHP v 5.5:
string(3272) "-----BEGIN RSA PRIVATE KEY-----
MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqA//...
-----END RSA PRIVATE KEY-----
"
string(800) "-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAO//...
-----END PUBLIC KEY-----
"
PHP v 5.6:
string(3272) "-----BEGIN PRIVATE KEY-----
MIIJQgIBADANBggsdisdVUCJDSQCjqgl2XqzR+bSv//...
-----END PRIVATE KEY-----
"
string(800) "-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BsdvQEFAAOdfAg8AMIICFAgEAo6oJdl6s0fm0r7QlaN/U//...
-----END PUBLIC KEY-----
"
因此,私钥头/尾根据您使用的PHP版本而变化。这不是一个真正的问题,但事实证明,如果系统创建了带有“RSA”的密钥头,则无法使用没有“RSA”的密钥,例如openssl\u sign():您将收到一个错误,说明“提供的密钥无法强制为私钥”。。。这就是它变得混乱的地方。
根据https://tls.mbed.org/kb/cryptography/asn1-key-structures-in-der-and-pem,在标题中带有“RSA”的私钥PEM格式和没有PKCS#1和PKCS#8的私钥PEM格式之间应该有区别,即带有有关算法等的附加信息。
因此,我遇到了严重的问题。为PHP5.6编写的相同软件无法在PHP5.5上运行。On可以通过手动将5.5标头替换为5.6兼容的标头来使用解决方法,但这只是一个“肮脏的黑客”。有没有“好”的方法来处理这个问题?
在设置时,此替换代码将尝试创建私钥,提取标头并“记住它”。然后检查运行时使用的所有键。如果找到的头文件不适合“本地”头文件,则需要进行交换。
但是我想有某种配置选项(我还没有设法找到),我可以在其中配置使用哪种格式?
接下来,更有趣的问题是:openssl究竟创建了什么格式?PKCS#1?PKCS#8?这也是可配置的吗?
没有配置(不幸的是)。只是PHP OpenSSL版本问题<代码>开始RSA私钥表示PKCS#1格式。没有RSA,它是PKCS#8。
使用PKCS1生成私钥RSA(我以前的帖子遇到了同样的问题)
“开始RSA私钥”和“开始私钥”之间的区别是什么。
您可以尝试使用phpsec库或从命令行调用openssl(exec()
)。我知道这对你没有帮助,但似乎还没有好的解决方案。
编辑
我稍微修改了你的测试脚本,并在我的windows 7上测试了私钥格式。
<?php
$keyPair = openssl_pkey_new(array(
"digest_alg" => 'sha512',
"private_key_bits" => 4096,
"private_key_type" => OPENSSL_KEYTYPE_RSA
));
$privateKey = null;
openssl_pkey_export($keyPair, $privateKey);
echo sprintf("PHP: %s\n", phpversion());
echo sprintf("OpenSSL: %s\n", OPENSSL_VERSION_TEXT);
echo sprintf("Private key header: %s\n", current(explode("\n", $privateKey)));
PHP: 5.4.44
OpenSSL: OpenSSL 0.9.8zf 19 Mar 2015
Private key header: -----BEGIN RSA PRIVATE KEY-----
PHP: 5.5.28
OpenSSL: OpenSSL 1.0.1p 9 Jul 2015
Private key header: -----BEGIN PRIVATE KEY-----
PHP: 5.6.12
OpenSSL: OpenSSL 1.0.1p 9 Jul 2015
Private key header: -----BEGIN PRIVATE KEY-----
这些结果根据openssl的变更日志再现了openssl的默认行为。
0.9.8n和1.0.0之间的变化[2010年3月29日]
将PKCS#8作为私钥的默认写入格式,取代传统格式。这种形式是标准化的、更安全的,并且不包含隐式MD5依赖项。[Steve Henson]
问题内容: 假设我在, 我想抽出时间来创作。是否有类似的东西 ? 问题答案: Redis不存储此信息。 您可以使用单独的密钥:
生成用于消息加密和解密的密钥对。 调用: web3.shh.newKeyPair([callback]) 参数: callback:Function - 可选的回调函数,其第一个参数为错误对象,第二个参数为返回结果 返回值: String - 密钥对生成成功则返回密钥ID,否则返回错误信息 示例代码: web3.shh.newKeyPair() .then(console.log); > "5e
我们需要使用Azure key vault创建RSA密钥对,并将RSA公钥复制到外部系统。其要求是外部系统使用公钥加密数据,内部系统与azure key vault对话并对数据进行解密。我还没有访问Azure key vault的权限,所以需要查看文档。我有两个基本问题: > 有没有一种方法可以使用Azure portal以文本格式导出RSA公钥,而不使用API(https://docs.micr
根据给定的私钥生成密钥对,并在保存后返回其ID。 调用: web3.shh.addPrivateKey(privateKey, [callback]) 参数: privateKey:String - 要导入的私钥,16进制字符串 callback:Function - 可选的回调函数,其第一个参数为错误对象,第二个对象为返回结果 返回值: String - 成功时返回ID,失败则返回错误信息 示
生成随机对称密钥,保存后返回ID,该对称秘钥用于消息加密和解密。 调用: web3.shh.newSymKey([callback]) 参数: callback:Function - 可选的回调函数,其第一个参数为错误对象,第二个参数为返回结果 返回值: String - 成功时返回ID,失败时返回错误信息 示例代码: web3.shh.newSymKey() .then(console.log