VB.NET 和 PHP 之间 RSA 的互操作性

发布于 2024-11-02 02:10:53 字数 1957 浏览 1 评论 0原文

我使用 OpenSSL 和 PHP 来生成 PEM 格式的公钥/私钥。

在 PHP 中,我创建公钥/私钥:

// generate a 1024 bit rsa private key
$privateKey = openssl_pkey_new(array(
    'private_key_bits' => 1024,
    'private_key_type' => OPENSSL_KEYTYPE_RSA,
));
// Save Private key
openssl_pkey_export_to_file($privateKey, 'privateKey');

// get the public key 
$keyDetails = openssl_pkey_get_details($privateKey);
// Save Public key
file_put_contents('publicKey', $keyDetails['key']);

在 VB.NET 中,我编写了以下代码:

'Public Key
Dim sReader As String ="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxYT5RaHelEBmk4Z7ppiVaPPBns/36sdY12F/AXETJVl2SYkjc672JMz ..... zQwIDAQAB"
Dim PublicKey As Byte() = Encoding.UTF8.GetBytes(sReader)
Dim Exponent As Byte() = {1, 0, 1}

    'Create a new instance of RSACryptoServiceProvider.
    Dim RSA As New RSACryptoServiceProvider()

    'Create a new instance of RSAParameters.
    Dim RSAKeyInfo As New RSAParameters()

    'Set RSAKeyInfo to the public key values. 
    RSAKeyInfo.Modulus = PublicKey
    RSAKeyInfo.Exponent = Exponent

    'Import key parameters into RSA.
    RSA.ImportParameters(RSAKeyInfo)

    'Create a UnicodeEncoder to convert between byte array and string.
    Dim ByteConverter2 As New UnicodeEncoding()

    'Create byte arrays to hold original, encrypted, and decrypted data.
    bytPlainText = Encoding.UTF8.GetBytes("Data to Encrypt")
    bytCipherText = RSA.Encrypt(bytPlainText, False)
    Dim sEncrypt99 As String = Convert.ToBase64String(bytCipherText)

但我无法使用私钥在 PHP 中解密“sEncrypt99

” 对于测试,我在“$encryptedData1”中复制了“sEncrypt99”

<?php
$privateKey = openssl_pkey_get_private('file://privateKey');
openssl_private_decrypt(base64_decode($encryptedData1), $sensitiveData2, $privateKey);

echo "sensitiveData = " . $sensitiveData2 . "<br>";
?>

没有错误,$sensitiveData2 是空的。奇怪的 .... 问题出在哪里?

雷姆:请原谅我的英语不好,我是法国人;)

I use OpenSSL with PHP to generate Public/Private Key in PEM Format.

In PHP I create Public/Private Key :

// generate a 1024 bit rsa private key
$privateKey = openssl_pkey_new(array(
    'private_key_bits' => 1024,
    'private_key_type' => OPENSSL_KEYTYPE_RSA,
));
// Save Private key
openssl_pkey_export_to_file($privateKey, 'privateKey');

// get the public key 
$keyDetails = openssl_pkey_get_details($privateKey);
// Save Public key
file_put_contents('publicKey', $keyDetails['key']);

In VB.NET I code this :

'Public Key
Dim sReader As String ="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxYT5RaHelEBmk4Z7ppiVaPPBns/36sdY12F/AXETJVl2SYkjc672JMz ..... zQwIDAQAB"
Dim PublicKey As Byte() = Encoding.UTF8.GetBytes(sReader)
Dim Exponent As Byte() = {1, 0, 1}

    'Create a new instance of RSACryptoServiceProvider.
    Dim RSA As New RSACryptoServiceProvider()

    'Create a new instance of RSAParameters.
    Dim RSAKeyInfo As New RSAParameters()

    'Set RSAKeyInfo to the public key values. 
    RSAKeyInfo.Modulus = PublicKey
    RSAKeyInfo.Exponent = Exponent

    'Import key parameters into RSA.
    RSA.ImportParameters(RSAKeyInfo)

    'Create a UnicodeEncoder to convert between byte array and string.
    Dim ByteConverter2 As New UnicodeEncoding()

    'Create byte arrays to hold original, encrypted, and decrypted data.
    bytPlainText = Encoding.UTF8.GetBytes("Data to Encrypt")
    bytCipherText = RSA.Encrypt(bytPlainText, False)
    Dim sEncrypt99 As String = Convert.ToBase64String(bytCipherText)

But I cant' decrypt "sEncrypt99" in PHP with the Private key

For the test I copied "sEncrypt99" in "$encryptedData1"

<?php
$privateKey = openssl_pkey_get_private('file://privateKey');
openssl_private_decrypt(base64_decode($encryptedData1), $sensitiveData2, $privateKey);

echo "sensitiveData = " . $sensitiveData2 . "<br>";
?>

No errors, $sensitiveData2 is empty. Strange ....
Where is the problem ?

Rem : Excuse for my poor english, I'm french ;)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

微凉 2024-11-09 02:10:53

我会检查 openssl 版本的公钥和 .NET 版本之间的模数和指数是否匹配。

对于 1024 位密钥,RSAParameters.Modulus 数组需要恰好为 128 字节。 DER 字节可能有一个前导零字节,使其成为 129 字节——请确保包含该字节。该 .NET 数组必须恰好为 128 字节(对于 1024 位密钥)。

我将从 openssl 转储公钥,并检查该数组。例如:

  1. 从 PHP/OpenSSL 端的私钥文件中单独获取公钥:

    $ openssl rsa -in private-key.pem -pubout -out public-key.pem

  2. 使用 openssl asn1parse 解析公钥:

    $ openssl asn1parse -in public-key.pem

    0:d=0 hl=3 l= 159 缺点:序列
    3:d=1 hl=2 l= 13 缺点:序列
    5:d=2 hl=2 l= 9 prim: 对象:rsaEncryption

    16:d=2 hl=2 l= 0 prim: NULL
    18:d=1 hl=3 l= 141 prim: BIT STRING

  3. 解析其中包含实际 RSA 公钥的 BIT STRING(PKCS1 ASN.1 形式):

    $ openssl asn1parse -in public-key.pem -strparse 18

     0:d=0 hl=3 l= 137 缺点:序列          
        3:d=1 hl=3 l= 129 初等:整数:B404886A7F0544C14AAE14EEE531A2D78122C9BFDB06E8C80433559A617FD159A05F8FD45500BBA63A1D07239C26BD8D32D3550D5DE AF7BF9C16D3E16BDE5A9BB56C378CB9E0E7DA9D3A5513482D74E1FDCCAC147D0E909 D1B620598F710B437D50DE8F80D5F742B6DA6E2D2ED1BBEBF89A40546103A8451B59D 8190633ACFA5
      135:d=1 hl=2 l= 3 prim: 整数:010001
    

该数组,从 B4 04 88 开始...(即您看到的密钥的任何值)应与您在 RSAParameters 中设置的字节数组匹配。我非常确定这个顺序(即 DER 顺序)就是您在 RSACryptoServiceProvider 模数数组中找到的内容(即 [0] = 0xb4、[1] = 0x04 等)此外,您可以验证指数(第二个整数)上面显示为 01 00 01。)

I would check that the modulus and exponent match between the openssl version of the public key, and the .NET version.

The RSAParameters.Modulus array needs to be exactly 128 bytes for a 1024-bit key. The DER bytes may have a leading zero-byte making it 129 bytes -- be sure not to include that. That .NET array must be exactly 128 bytes (for a 1024-bit key.)

I would dump the public key from openssl, and check the array. For example:

  1. Get the public key alone from the private key file on the PHP/OpenSSL side:

    $ openssl rsa -in private-key.pem -pubout -out public-key.pem

  2. Parse the public-key using openssl asn1parse:

    $ openssl asn1parse -in public-key.pem

    0:d=0 hl=3 l= 159 cons: SEQUENCE
    3:d=1 hl=2 l= 13 cons: SEQUENCE
    5:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption

    16:d=2 hl=2 l= 0 prim: NULL
    18:d=1 hl=3 l= 141 prim: BIT STRING

  3. Parse the BIT STRING which has the actual RSA public key in it (PKCS1 ASN.1 form):

    $ openssl asn1parse -in public-key.pem -strparse 18

        0:d=0  hl=3 l= 137 cons: SEQUENCE          
        3:d=1  hl=3 l= 129 prim: INTEGER           :B404886A7F0544C14AAE14EEE531A2D78122C9BFDB06E8C80433559A617FD159A05F8FD45500BBA63A1D07239C26BD8D32D3550D5DEAF7BF9C16D3E16BDE5A9BB56C378CB9E0E7DA9D3A5513482D74E1FDCCAC147D0E909D1B620598F710B437D50DE8F80D5F742B6DA6E2D2ED1BBEBF89A40546103A8451B59D8190633ACFA5
      135:d=1  hl=2 l=   3 prim: INTEGER           :010001
    

That array, starting at B4 04 88 ... (i.e. whatever value you see for your key) should match the byte array you are setting in the RSAParameters. I'm pretty sure that this order (i.e. DER order) is what you find in the RSACryptoServiceProvider modulus array (i.e. [0] = 0xb4, [1] = 0x04, etc.) Also, you can verify the exponent (the second integer showing above as 01 00 01.)

最近可好 2024-11-09 02:10:53

我知道这个帖子有点过时了,但我正在尝试完全相同的事情。我遇到了“file://privateKey”的问题。废弃它并使用 fopen,或将密钥存储在变量中。为我工作:)

I know this thread is slightly outdated but im attempting the exact same thing. I came across a problem with 'file://privateKey'. Scrap it and use fopen, or store the key in a variable. Worked for me :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文