【问题标题】:Interoperability of RSA between VB.NET and PHPVB.NET 和 PHP 之间 RSA 的互操作性
【发布时间】:2011-04-16 07:59:29
【问题描述】:

我使用 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 为空。奇怪的 .... 问题出在哪里 ?

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

【问题讨论】:

    标签: php vb.net encryption openssl rsa


    【解决方案1】:

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

    对于 1024 位密钥,RSAParameters.Modulus 数组需要正好是 128 个字节。 DER 字节可能有一个前导零字节,使其成为 129 个字节——请确保 not 包括它。该 .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: OBJECT :rsaEncryption

      16:d=2 hl=2 l= 0 prim: NULL
      18:d=1 hl=3 l= 141 prim: 位串

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

      $ 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
      

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2023-04-04
        • 2011-03-16
        • 2013-06-08
        • 1970-01-01
        • 2014-05-04
        • 2010-10-07
        • 1970-01-01
        • 2011-06-22
        • 2021-05-06
        相关资源
        最近更新 更多