为啥 Linux 或 Windows 下的私钥字符串不同?

Posted

技术标签:

【中文标题】为啥 Linux 或 Windows 下的私钥字符串不同?【英文标题】:Why different private key strings under Linux or Windows?为什么 Linux 或 Windows 下的私钥字符串不同? 【发布时间】:2012-03-29 12:13:58 【问题描述】:

当我使用以下 php 代码(和相同的配置参数)创建私钥字符串时,它们被包含在不同的字符串之间:

$configs = array('config' => 'OpenSSL.cnf',
                 'digest_alg' => 'sha1',
                 'x509_extensions' => 'v3_ca',
                 'req_extensions' => 'v3_req',
                 'private_key_bits' => 2048,
                 'private_key_type' => OPENSSL_KEYTYPE_RSA,
                 'encrypt_key' => false,
                 'encrypt_key_cipher' => OPENSSL_CIPHER_3DES);

$privateKeyResourceId = openssl_pkey_new($this->configs);                       
openssl_pkey_export($privateKeyResourceId, $privateKeyString);

在 Linux 上,$privateKeyString 如下所示:

-----开始私钥-----NBgkqhkiG9w0BAQE....ASDFasjkfa-----结束私钥-----

在 Windows 上,$privateKeyString 如下所示:

-----BEGIN RSA PRIVATE KEY-----NBgkqhkiG9E....ASDFasjkfa-----END RSA PRIVATE KEY-----

当我将 Windows 私钥字符串复制到 Linux 时,它一直有效,直到我从开始/结束中删除“RSA”(反之亦然)。这是为什么呢?

【问题讨论】:

OpenSSL 支持不止一种私钥格式。正在使用哪种格式的 PEM 标头标识符。第一个是标准 PKCS 格式,并包含一个标识符,表明它是一个 RSA 密钥。第二个是特定于 RSA 的格式,因此不需要该标识符。默认格式在 PHP 5.2.9 和 5.3.3 之间发生了变化。 感谢您的评论。这意味着这不是操作系统问题。必须检查一下。 绝对不是操作系统问题。这是一个PHP问题。 (两者都没有损坏,只是如果您的代码需要一个并得到另一个,...) 【参考方案1】:

这是 openssl 版本而不是 PHP 之间的差异。以下 openssl 命令在 openssl 版本 0.9.x 和 1.0.0x 之间创建不同的关键页眉/页脚:

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

对于 0.9.x 版本,关键页眉/页脚是:

-----开始 RSA 私钥-- -----结束 RSA 私钥-----

对于 1.0.0x 版本,关键页眉/页脚是:

-----开始私钥----- -----结束私钥-----

对于更高版本的openssl,我必须通过以下命令运行密钥文件以使其与旧的默认值兼容:

openssl rsa -in mykey.key -text > mykey.pem

“mykey.pem”文件具有与 AWS 和类似服务兼容的页眉/页脚(和格式)。

【讨论】:

谢谢!这解决了我在尝试将密钥上传到 Amazon AWS 时遇到的问题!【参考方案2】:

根据user note php.net,这是一个已知问题:

请注意,旧版本的 PHP/OpenSSL 导出 RSA 私钥时带有 '-----BEGIN RSA PRIVATE KEY-----' PEM 标签,其中仅包含 privateKey 字段,因此省略了版本和privateKeyAlgorithm 字段。

这样做的效果是,如果您将其转换为 DER,并且 然后回到 PEM,但使用'-----BEGIN PRIVATE KEY-----' PEM 标签, openssl_pkey_get_privatekey() 函数将失败!Senthryl 的 代码可用于在 PEM 编码数据前加上版本和 再次使用 privateKeyAlgorithm 字段。

较新的 PHP/OpenSSL 版本导出 RSA 私钥 '-----BEGIN PRIVATE KEY-----' PEM 标签,包含版本号和 privateKeyAlgorithm 字段。

我注意到我的两台服务器之间存在这些差异:

Fedora Core 12 x64 上的 PHP 版本 5.3.3(OpenSSL 1.0.0a-fips 2010 年 6 月 1 日)

Fedora Core 10 x64 上的 PHP 版本 5.2.9(OpenSSL 0.9.8g 2007 年 10 月 19 日)

【讨论】:

以上是关于为啥 Linux 或 Windows 下的私钥字符串不同?的主要内容,如果未能解决你的问题,请参考以下文章

OpenSSH生成的私钥如何在putty中使用?

Windows下生成 公钥 私钥以及 配置 Filezilla中的 SFTP的私钥

如何让 Windows 上的 TortoiseHg (Mercurial) 使用生成的私钥文件(由 Puttygen 生成)?

部署Swarm挖矿节点,如何导出蜂群Windows版本中的私钥到MetaMask(狐狸钱包)

如何获取“开发人员ID应用程序”或“开发人员ID安装程序”证书的私钥?

如何从 NEAR 协议中的私钥和/或帐户 ID 获取公钥?