RSA Encrypt в PHP для расшифровки в .NET - PullRequest
9 голосов
/ 09 апреля 2010

В PHP я зашифровываю сообщение RSA для дешифрования приложением .NET ... но я получаю исключение "Плохой ключ" из .NET ....

Для шифрования RSA я использую PEAR-класс Crypt_RSA-> шифрование с помощью открытого ключа (который является модулем, пара экспонент), который я получаю от работающей системы шифрования в .NET ...

Полагаю, самый простой вопрос -> означает ли "Плохой ключ", что он вообще не может расшифровать сообщение? IE, он не зашифрован правильно?

Более сложный вопрос-> Есть ли что-то конкретное в шифровании RSA, которое вызывает причуды между .NET и PHP?

Ответы [ 2 ]

14 голосов
/ 10 апреля 2010

Предупреждение безопасности : используйте OAEP, не PKCS # 1 .

Если вы хотите использовать решение, не требующее расширения openssl, попробуйте phpseclib Crypt_RSA. Примеры следующие:

Расшифровка с заполнением PKCS # 1:

openssl rsautl -inkey privatekey.txt -encrypt -in plaintext.txt -out ciphertext.txt

<?php
include('Crypt/RSA.php');

$rsa = new Crypt_RSA();
$rsa->loadKey(file_get_contents('privatekey.txt'));
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
echo $rsa->decrypt(file_get_contents('ciphertext.txt'));
?>

Шифрование с заполнением PKCS # 1:

<?php
include('Crypt/RSA.php');

$rsa = new Crypt_RSA();
$rsa->loadKey(file_get_contents('privatekey.txt'));
$rsa->loadKey($rsa->getPublicKey());
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
echo $rsa->encrypt('1234567890');
?>

openssl rsautl -inkey privatekey.txt -decrypt -in ciphertext.txt -out plaintext.txt

Расшифровка с использованием OAEP:

openssl rsautl -inkey privatekey.txt -encrypt -oaep -in plaintext.txt -out ciphertext.txt

<?php
include('Crypt/RSA.php');

$rsa = new Crypt_RSA();
$rsa->loadKey(file_get_contents('privatekey.txt'));
echo $rsa->decrypt(file_get_contents('ciphertext.txt'));
?>

Шифрование с заполнением OAEP:

<?php
include('Crypt/RSA.php');

$rsa = new Crypt_RSA();
$rsa->loadKey(file_get_contents('privatekey.txt'));
$rsa->loadKey($rsa->getPublicKey());
echo $rsa->encrypt('1234567890');
?>

openssl rsautl -inkey privatekey.txt -decrypt -oaep -in ciphertext.txt -out plaintext.txt

phpseclib можно загрузить с http://phpseclib.sourceforge.net/

Удачи!

3 голосов
/ 10 апреля 2010

Crypt_RSA на PEAR не использует кодировку PKCS # 1. Я подозреваю, что именно поэтому .NET выдает сообщение об ошибке.

В качестве примера взлома я создал php-скрипт, используя Crypt_RSA для шифрования строки «1234567» (я пропущу показ загрузки ключа):

print $rsa_obj->encryptBinary("1234567", $key_pair->getPublicKey());

Взяв вывод этого и передав его через инструмент командной строки openssl, выдает следующую ошибку:

$ ./crypt | openssl rsautl -inkey privkey.pem -decrypt
RSA operation error
18437:error:04065084:rsa routines:RSA_EAY_PRIVATE_DECRYPT:data too large for modulus:fips_rsa_eay.c:558:

openssl ожидает заполнение PKCS # 1 по умолчанию, но добавление флага -raw (без заполнения) к openssl также не помогает.

Использование расширения openssl в php дает правильное заполнение (по умолчанию PKCS # 1, доступны другие):

$pem = file_get_contents("pubkey.pem");
$key = openssl_pkey_get_public($pem);

$encrypted = "";
if(openssl_public_encrypt("1234567", $encrypted, $key)) {
  print $encrypted;
} else {
  print "failed\n";
}

И расшифровать код в php:

$pem = file_get_contents("privkey.pem");
$key = openssl_pkey_get_private($pem);

$enc_data = file_get_contents("openssl.crypted");
$decrypted = "";
if(openssl_private_decrypt($enc_data, $decrypted, $key)) {
  print "$decrypted\n";
} else {
  print "failed\n";
}

Сертификаты в контексте RSA являются сертификатами X.509, которые являются ключами RSA плюс данные об этих ключах. Сертификаты X.509 используются в SSL, но не обязательны для использования RSA.

...