【问题标题】:Generate RSA private SSH key in PHP在 PHP 中生成 RSA 私有 SSH 密钥
【发布时间】:2023-03-29 00:49:01
【问题描述】:

我已经用 PHP OpenSSL 生成了一个 SSH 密钥:

$rsaKey = openssl_pkey_new(array( 
    'private_key_bits' => 4096,
    'private_key_type' => OPENSSL_KEYTYPE_RSA,
));
$privKey = openssl_pkey_get_private($rsaKey); 
openssl_pkey_export($privKey, $pem);

这导致$pem 看起来像这样:

-----开始私钥-----
MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQC8ggt6rVHYnqNP
...
e95+EXbPc6THyWt9pgwOsJltpylIYG4=
-----结束私钥-----

但我无法使用此密钥进行身份验证。在我可以使用它之前,我必须使用这个命令来转换它:

openssl rsa -in xxx.key -outform pem > xxx.key2

转换的结果是这样的:

-----开始 RSA 私钥--
MIIJKQIBAAKCAgEAvIILeq1R2J6jT+xjlK5NrOqFZTOJ4PByvgPQNbb2Kp7c3W15
...
o1t2KBkaSoR+JyOPOZakq5BLv8lgD3vefhF2z3Okx8lrfaYMDrCZbacpSGBu
-----结束 RSA 私钥-----

两者都是 PEM 格式,但第二个是 RSA 私钥。有了第二个,PHP就可以登录了。所以我需要一个以RSA PRIVATE KEY 开头的密钥,而不仅仅是PRIVATE KEY。如何使用 PHP 和 OpenSSL PHP 实现来创建它?

【问题讨论】:

  • 您知道这些被称为 private 密钥是有原因的,对吧?你会想把这个扔掉的。
  • @Sammitch:当然。但是没有理由隐藏它们。它们是在非生产环境中生成的,不被任何系统使用。
  • 这似乎取决于版本。在 PHP 5.5.31 上运行它,我得到 BEGIN RSA PRIVATE KEY,但在 PHP 7.0.4 上运行它我得到 BEGIN PRIVATE KEY。也可能与编译时使用的 OpenSSL 版本有关。
  • 这是一个很好的问题。关于刚才@miken32 的评论,我正在通过 CLI 运行 PHP 5.5.30,我得到了“私钥”。运行openssl rsa -in myKey.pem -check 说“RSA 密钥正常”,然后继续将其转换为您期望看到的内容。该文档具有误导性,因为它表明您正在做的事情应该产生一个 RSA 密钥(通过两端的 cmets 显而易见)
  • @miken32:谢谢。我可以在我的本地机器上重现它。我刚刚在我们的测试环境中安装了 PHP 7。那不是问题。问题似乎是 OpenSSL 版本。目前,它是 OpenSSL 1.0.1k。我尝试更新它。

标签: php ssh openssl rsa private-key


【解决方案1】:

所以,这些是two different key types。您正在寻找 PKCS #1,但正在寻找 PKCS #8。

这似乎与 PHP 使用的 OpenSSL 版本有关。自 1.0 起的版本创建一个 PKCS #8 文件,nothing the PHP developers 想要处理它。使用此命令从命令行执行此操作时会出现同样的问题:

openssl req -new -keyout mykey.key -out mycertreq.csr -nodes -sha1 -newkey rsa:2048

您可以尝试使用名为 phpseclib 的外部库,虽然我自己没有尝试过:

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

$rsa = new Crypt_RSA();
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_OPENSSH);
$result = $rsa->createKey();
echo $result["privatekey"];
?>

【讨论】:

  • 我已经看到这个并且害怕“PHP 4”。我刚刚检查了 Github 存储库,它并没有我之前想象的那么过时。如果我找不到其他 OpenSSL 版本的解决方案,我会尝试一下。
  • 是的,我会更新链接,因为我认为 Sourceforge 不是最新的!