В PHP я RSA, шифруя сообщение, которое будет расшифровано .NET-приложением … но я продолжаю получать исключение «Bad Key» из .NET ….
Для шифрования RSA я использую класс PEAR Crypt_RSA-> шифрование с открытым ключом (который является модулем, парами экспонентов), которые я получаю из рабочей системы шифрования в .NET …
Я думаю, самый простой вопрос -> «Плохой ключ» означает, что он не может расшифровать сообщение вообще? IE, он не зашифрован правильно?
Более сложный вопрос: есть ли что-то конкретное в шифровании RSA, которое вызывает причуды между .NET и PHP?
Предупреждение о безопасности . Используйте OAEP, а не PKCS # 1 .
Если вы хотите использовать решение, не требующее расширения openssl, попробуйте crypt_RSA от phpseclib. Примеры:
Расшифровка с помощью дополнения 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'); ?>
в<?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')); ?>
в<?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'); ?>
в<?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/
Удачи!
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.