RSA расшифровывает данные на С# (.NET 3.5), которые были зашифрованы с помощью openssl в php 5.3.2

Может быть, кто-то сможет меня прояснить. Я занимаюсь серфингом на этом некоторое время теперь.

Шаг №1: Создайте корневой сертификат

Key generation on unix
1) openssl req -x509 -nodes -days 3650 -newkey rsa:1024 -keyout privatekey.pem -out mycert.pem

2) openssl rsa -in privatekey.pem -pubout -out publickey.pem

3) openssl pkcs12 -export -out mycertprivatekey.pfx -in mycert.pem -inkey privatekey.pem -name "my certificate"

Шаг № 2: Работает ли корневой сертификат на php: ДА

PHP side

Я использовал publickey.pem, чтобы прочитать его в php:

$publicKey = "file://C:/publickey.pem";
$privateKey = "file://C:/privatekey.pem";
$plaintext = "123";

openssl_public_encrypt($plaintext, $encrypted, $publicKey);
$transfer = base64_encode($encrypted);
openssl_private_decrypt($encrypted, $decrypted, $privateKey);

echo $decrypted;  // "123"

OR

$server_public_key = openssl_pkey_get_public(file_get_contents("C:\publickey.pem"));
// rsa encrypt
openssl_public_encrypt("123", $encrypted, $server_public_key);

//and the privatekey.pem to check if it works:
openssl_private_decrypt($encrypted, $decrypted, openssl_get_privatekey(file_get_contents("C:\privatekey.pem")));

echo $decrypted;  // "123"

Приходя к выводу, что шифрование/дешифрование отлично работает на стороне php с этими файлами корневого сертификата openssl.


Шаг № 3. Работает ли корневой сертификат в .NET: ДА

C# side

Таким же образом я читаю ключи в консольной программе .net С#:

X509Certificate2 myCert2 = null;
RSACryptoServiceProvider rsa = null;

try
{
    myCert2 = new X509Certificate2(@"C:\mycertprivatekey.pfx", "password");
    rsa = (RSACryptoServiceProvider)myCert2.PrivateKey;
}
catch (Exception e)
{
    Console.writeln(e.message); // because I left a blank catch block, I did not realize there was an exception! I missed the password for the certificate.
}

byte[] test = {Convert.ToByte("123")};

string t = Convert.ToString(rsa.Decrypt(rsa.Encrypt(test, false), false));

Приходя к выводу, что шифрование/дешифрование отлично работает на стороне С# с этими файлами корневого сертификата openssl.


Шаг № 4: Зашифровать в php и расшифровать в .NET: ДА

PHP side
$onett = "123"
....
openssl_public_encrypt($onett, $encrypted, $server_public_key);
$onettbase64 = base64_encode($encrypted);

копировать - вставить $ onettbase64 ( "LkU2GOCy4lqwY4vtPI1JcsxgDgS2t05E6kYghuXjrQe7hSsYXETGdlhzEBlp + qhxzTXV3pw + AS5bEg9CPxqHus8fXHOnXYqsd2HL20QSaz + FjZee6Kvva0cGhWkFdWL + ANDSOWRWo / OMhm7JVqU3P / 44c3dLA1eu2UsoDI26OMw =") в C # программы:

C# side
byte[] transfered_onett = rsa.Decrypt(Convert.FromBase64String("LkU2GOCy4lqwY4vtPI1JcsxgDgS2t05E6kYghuXjrQe7hSsYXETGdlhzEBlp+qhxzTXV3pw+AS5bEg9CPxqHus8fXHOnXYqsd2HL20QSaz+FjZee6Kvva0cGhWkFdWL+ANDSOWRWo/OMhm7JVqU3P/44c3dLA1eu2UsoDI26OMw="), false);

string result = System.Text.Encoding.UTF8.GetString(transfered_onett); // "123"

Нет проблем.


person panny    schedule 05.06.2010    source источник
comment
Кстати, я думаю, вы имели в виду .NET 3.5. С# 3.5 нет.   -  person John Saunders    schedule 05.06.2010
comment
правильно, я имел в виду .NET 3.5   -  person panny    schedule 05.06.2010
comment
Итак, у вас есть 2 образца, оканчивающихся на «работает нормально», так в чем собственно вопрос?   -  person Henk Holterman    schedule 05.06.2010
comment
Вы уверены, что правильно читаете закрытый ключ на стороне .NET? Все конструкторы X509Certificate2, которые читают PFX-файлы, также требуют аргумента пароля.   -  person President James K. Polk    schedule 05.06.2010
comment
@GregS ты прав! В этом была проблема.   -  person panny    schedule 05.06.2010


Ответы (2)


Вам необходимо использовать один из конструкторов X509Certificate2, предназначенных для файлов PFX (он же pkcs#12). Они принимают аргумент пароля. В исходном примере вы молча проглатывали все исключения, поэтому пропустили ошибку.

person President James K. Polk    schedule 05.06.2010

Это решено. Я забыл заполнить блок catch, поэтому я не понял, что было исключение с чтением сертификата на стороне С#. С прочитанным сертификатом расшифровка теперь не проблема.

person panny    schedule 05.06.2010
comment
Отметьте это как ответ тогда. - person Adam Driscoll; 05.06.2010
comment
Я не могу ;) Я должен ждать два дня :D Хотя GregS нашел проблему, я решил ее с другим другом всего несколько минут назад, но я отмечу решение GregS. - person panny; 05.06.2010