2011-04-16 45 views
0

我使用OpenSSL和PHP生成PEM格式的公钥/私钥。VB.NET和PHP之间RSA的互操作性

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

,但我不能”解密 “sEncrypt99” PHP中的私钥

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

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

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

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

REM:借口,我的英语不好,我是法国人;)

回答

0

我会检查公钥的OpenSSL的版本,和.NET版本之间的模数和指数相匹配。

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

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

  1. 从私有密钥文件独自坐上PHP/OpenSSL的方公钥:

    $ OpenSSL的RSA -in私人key.pem -pubout退房手续公共key.pem

  2. 用openssl asn1parse解析公钥:

    $ OpenSSL的asn1parse -in公共key.pem

    0:d = 0 HL = 3,L = 159个缺点:SEQUENCE
    3:d = 1个HL = 2 L = 13个缺点:SEQUENCE
    5:d = 2 HL = 2 L = 9拘谨:OBJECT:与RSAEncryption

    16:d = 2 HL = 2 L = 0拘谨:NULL
    18:d = 1个HL = 3,L = 141拘谨:BIT STRING

  3. 解析,其具有在它的实际的RSA公钥(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。)

0

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

+0

你可以发布一些代码来解释吗? – LeMoussel 2011-09-13 05:08:46