【问题标题】:Can an RSA OpenSSL key generated with C/C++ be decrypted with PHP?可以使用 PHP 解密使用 C/C++ 生成的 RSA OpenSSL 密钥吗?
【发布时间】:2015-08-01 09:53:31
【问题描述】:

在许多情况下,安全软件涉及(桌面)应用程序和 Web 界面之间的交互。对于(RSA)非对称加密,我们使用 OpenSSL 的C library(目前版本为 1.0.2d),我们使用 openssl PHP library

所有标准的东西:

  • 私有加密 (C++) 数据和公开解密 (PHP)
  • 公共加密 (C++) 数据和私有解密 (PHP)

有效。反之亦然:PHP -> C++ 和 C++ -> PHP

此外,使用 PHP 生成加密的私钥并使用 C/C++ 解密该密钥也可以。但不是相反:我想用 PHP 解密一个用 C++ 生成和加密的私钥。注意:这与使用密钥加密/解密数据不同。

问题似乎是 C OpenSSL 加密私钥的方式。仅仅知道加密密钥的算法是不够的(在我们的例子中是 aes-256-cbc)。密码也被拉伸了。 OpenSSL 加密密钥的方式随着时间的推移发生了变化。我将举例说明它现在的样子。

使用 OpenSSL C/C++ 生成的私钥的部分标头如下所示:

-----BEGIN ENCRYPTED PRIVATE KEY-----
MIISnzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQI/epYUO8+LygCAggA

而使用 openssl PHP 生成的 pem 编码私钥的部分标头看起来像:

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,372DA3A61BEB36AA

bc9NsTtdfcMW9t9isDPgl86aME223ockk9pIGDduEyrTS7zh1gwHWSWnD2efbxLd

我曾尝试使用一些 PHP 扩展,例如 phpseclib,但我仍然无法在 PHP 程序中使用由 C OpenSSL 生成的私钥。公钥没有加密,可以在两种语言之间毫无问题地交换。

为了使用 C OpenSSL 生成 RSA 密钥,我们使用 EVP_PKEY 结构。

作者于 2015 年 8 月 12 日编辑

作为对 neubert 的回复,我使用 OpenSSL 实用程序“openssl genpkey”生成了一个加密的 RSA 私钥:

OpenSSL> genpkey -algorithm RSA -out c:\temp\test512.pem -aes-256-cbc -pass pass:1234 -pkeyopt rsa_keygen_bits:512

所以密钥长度为 512 位,密码为“1234”。

为了获得密钥的未加密形式,我使用了“openssl pkey”:

OpenSSL> pkey -in c:\temp\test512.pem  -out c:\temp\test512naked.pem

注意,在 Windows 上,openssl 可执行文件名为“openssl.exe”。

这里是关键:

-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIBrzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQITePvOJ8u8lECAggA
MB0GCWCGSAFlAwQBKgQQ9gg/UzRleUGcOGK9P18fiASCAWCIo5c7q/HT7IcdtpiJ
y1bTj+SsqAilQIPIf1wtN2VjuVDQMSN35neI2X9TL3H9dNd6BVwJnzkfKbEAKK1+
ipj2KjOIVipctul6QIh9TS+MkGO0ZI+TaMJX4TaoPanLkQ00bOhnFod9W5UHZvVU
EdVx1+9bvvEngFqqweKjAfSySQ6Y9JD3E/ZSg1Bja3c9uLTlYFuMSs6S9iVUimlw
BCJXlfeHL5o331qwpAPjzOFD4ztTsOpnpXIt3y9l53u6UThHMWiTon5NpJgeQGny
GXSWvfZ4mhOjpUixrgFC/VqLjAHNvG9mqC4xoufNK3/QPCMNBsGpJ2gUSoX4/SkA
edUaPFhKRja8f9cvBW6vs67/lvAYjQ2tZOR8l7Jgj5AL3mKi8wyD/QISrJqFDrq6
dYLqyofv+5OJRWtAE4KJEASTVIJktnvTaxTI7gB+cRp/BHdDLvrTmfZ7UbI9Zx+K
ZLia
-----END ENCRYPTED PRIVATE KEY-----

-----BEGIN PRIVATE KEY-----
MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqxGy/AXwTEvx+moN
eRMNO/bWYBE+dX7kNROzswC2SzO6+NgYqKKIkYb8+Iho2ssuoYVWc62Gk37gxEhi
QrIDRQIDAQABAkEAlsA1I0S0evfeGNfGYbC5U+N1DRmFGhOlVWS0UgVJn8BYIpQI
fjseZ3xXhtfZypzTzc9VZKUJedi3cv7Ju9gqYQIhANzE+XbiytUzBFTzKuRanMEn
o6noJDGiaVktWvbbZEkpAiEAxl5VedZ1PCU5Qpd+1u7agIZfSBwWnkI0nnxO5Slo
AL0CIEWc0rCbGKwbVx1WQ8sXi2AYmLHFokwIU0GsXIeEbF3pAiALvbOjdX0U5UMh
XOQmBpcqOknTc84m6dZBdywYRj4gpQIgfg/KLv7cv/mGoe8tvh3geYTpnZ2HRwDN
O9Kal0WOaiw=
-----END PRIVATE KEY-----

【问题讨论】:

    标签: php c++ c openssl php-openssl


    【解决方案1】:

    -----BEGIN ENCRYPTED PRIVATE KEY----- 密钥是 PKCS8 编码的。正在使用的对称密码(和 IV)嵌入在密钥中。 phpseclib 目前只支持 pbeWithMD5AndDES-CBC。 pbe 部分表示它正在使用 PBKDF1。也许这就是您的密钥所使用的,也很难说。

    基本上,如果您可以生成另一个相同的密钥并将其发布 - 连同用于解锁它的密码 - 那会很有帮助。我可以将对该密码 / pbkdf 的支持添加到 phpseclib。

    如果您想尝试自己修改 phpseclib,请随意这样做。检查以下 switch 语句:

    https://github.com/phpseclib/phpseclib/blob/1.0.0/phpseclib/Crypt/RSA.php#L1225

    但就像我说的,尽管如此 - 我也能做到 - 我只需要你提供密钥(或格式相同的密钥!)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多