简体   繁体   English

用C / C ++生成的RSA OpenSSL密钥可以用PHP解密吗?

[英]Can an RSA OpenSSL key generated with C/C++ be decrypted with PHP?

In a number of situations security software involves the interaction between (desktop) applications and web interfaces. 在许多情况下,安全软件都涉及(桌面)应用程序和Web界面之间的交互。 For (RSA) asymmetric encryption we use the C library of OpenSSL (version 1.0.2d at present) and we use the openssl PHP library . 对于(RSA)非对称加密,我们使用OpenSSL的C库 (当前为1.0.2d版),而我们使用openssl PHP库

All the standard stuff: 所有标准的东西:

  • private encrypt (C++) data and public decrypt (PHP) 私有加密(C ++)数据和公共解密(PHP)
  • public encrypt (C++) data and private decrypt (PHP) 公共加密(C ++)数据和私有解密(PHP)

works. 作品。 And also the other way around: PHP -> C++ and C++ -> PHP 还有另一种方法:PHP-> C ++和C ++-> PHP

In addition generating an encrypted private key with PHP and decrypting that key with C/C++ also works. 此外,还可以使用PHP生成加密的私钥,并使用C / C ++解密该私钥。 But not the other way around: I want to decrypt with PHP a private key that is generated and encrypted with C++. 但不是这样:我想用PHP解密用C ++生成和加密的私钥。 Note: this is different from encrypting/decrypting data with the keys. 注意:这与使用密钥加密/解密数据不同。

The problem seems to be the way C OpenSSL encrypts a private key. 问题似乎是C OpenSSL加密私钥的方式。 It is not enough to know the algorithm with which the key is encrypted (aes-256-cbc in our case). 仅仅知道加密密钥的算法是不够的(在我们的例子中是aes-256-cbc)。 The password is also stretched. 密码也被拉伸。 The way the key is encrypted by OpenSSL has changed over time. 随着时间的流逝,OpenSSL加密密钥的方式发生了变化。 I will give an example how it looks now. 我现在举一个例子。

Part of the the header of the private key generated with OpenSSL C/C++ looks like: 用OpenSSL C / C ++生成的私钥标头的一部分如下:

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

Whereas part of the header of a pem-encoded private key generated with openssl PHP looks like: 而使用openssl PHP生成的经过pem编码的私钥的标头的一部分如下所示:

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

bc9NsTtdfcMW9t9isDPgl86aME223ockk9pIGDduEyrTS7zh1gwHWSWnD2efbxLd

I have tried to use some PHP extensions, like phpseclib , but I still cannot use a private key generated with C OpenSSL in PHP programs. 我试图使用一些PHP扩展名,例如phpseclib ,但是我仍然不能在PHP程序中使用C OpenSSL生成的私钥。 The public keys are not encrypted and they can be exchanged between the two languages without any problem. 公钥未加密,可以在两种语言之间交换而不会出现任何问题。

For generating RSA keys with C OpenSSL we use the EVP_PKEY structure. 为了使用C OpenSSL生成RSA密钥,我们使用EVP_PKEY结构。

Edited by author on August 12, 2015 由作者于2015年8月12日编辑

In reply to neubert I have generated an encrypted private RSA key with the OpenSSL utility "openssl genpkey": 为了回应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

So key length is 512 bits and password "1234". 因此,密钥长度为512位,密码为“ 1234”。

To get the unencrypted form of the key I used "openssl pkey": 为了获得密钥的未加密形式,我使用了“ openssl pkey”:

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

Note on Windows the openssl executable is called "openssl.exe". 注意在Windows上,openssl可执行文件称为“ openssl.exe”。

Here are the keys: 这是关键:

-----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-----

and

-----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-----

The -----BEGIN ENCRYPTED PRIVATE KEY----- key is PKCS8 encoded. -----BEGIN ENCRYPTED PRIVATE KEY-----加密-----BEGIN ENCRYPTED PRIVATE KEY-----密钥是PKCS8编码的。 The symmetric cipher being used (and the IV) is embedded in the key. 所使用的对称密码(和IV)嵌入在密钥中。 phpseclib currently only supports pbeWithMD5AndDES-CBC. phpseclib当前仅支持pbeWithMD5AndDES-CBC。 The pbe part means that it's using PBKDF1. pbe部分表示它正在使用PBKDF1。 Maybe that's what your key is using, too, hard to say. 也许这就是您的密钥所使用的,也很难说。

Basically, if you can generate another identical key and post it - along with the password to unlock it - that'd be helpful. 基本上,如果您可以生成另一个相同的密钥并发布它(连同用于解锁它的密码),那将很有帮助。 I can add support to that cipher / pbkdf to phpseclib. 我可以将对cipher / pbkdf的支持添加到phpseclib中。

If you want to try modifying phpseclib yourself feel free to do so. 如果您想尝试修改phpseclib,请随时进行修改。 Check the following switch statement: 检查以下switch语句:

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

But like I said, tho - I can do it too - I just need you to provide the key (or an identically formatted one!) 但是就像我说的那样-我也可以做到-我只需要您提供密钥(或格式完全相同的密钥!)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM