2010-04-09 43 views
9

En PHP estoy encriptando un mensaje RSA para ser descifrado por la aplicación .NET ... pero sigo recibiendo una excepción de "Clave incorrecta" de .NET ....RSA Encriptar en PHP para descifrar en .NET

Para encriptación RSA, estoy usando la clase PEAR Crypt_RSA-> encriptando con la clave pública (que es un módulo, par exponente) Obtengo del sistema de encriptación en .NET ...

Supongo que la pregunta más fácil sería -> ¿"Clave incorrecta" significa que no puede descifrar el mensaje en absoluto? IE, no está encriptado correctamente?

La pregunta más difícil es-> ¿Hay algo específico sobre el cifrado RSA que cause caprichos entre .NET y PHP?

+1

¿Podría haber un problema con la clave en sí? Caracteres impares, ¿problema entre UNICODE y UTF-8? –

+0

Es posible que esté utilizando diferentes almohadillas. – SLaks

+0

RE: Relleno: ¿se refiere a la cadena en sí? En este caso, es exactamente 32 bytes, que es divisible por 8 ... ¿así que lo tengo cubierto? – user312904

Respuesta

3

Crypt_RSA en PEAR no utiliza la codificación PKCS # 1. Sospecho que es por eso que .NET te está dando un mensaje de error.

Como un ejemplo de que se rompa, he creado un script php usando Crypt_RSA para cifrar la cadena "1234567" (voy a omitir que muestra la carga de claves):

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

Tomando la salida de ese y de la tubería se a través de la herramienta de línea de comando openssl da el siguiente error:

$ ./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 espera PKCS # 1 de relleno por defecto, pero añadiendo el -raw (sin relleno) de la bandera de OpenSSL no ayuda tampoco.

Usando la extensión openssl en php da el relleno adecuado (por defecto es PKCS # 1, otros disponibles):

$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"; 
} 

Y el código de descifrado en 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"; 
} 

Certificados en el contexto de RSA son certificados X.509, que son las claves RSA más los datos sobre esas claves. Los certificados X.509 se usan en SSL, pero no se requiere el uso de RSA.

14

Security Warning: Use OAEP, not PKCS#1 .

Si desea utilizar una solución que no requiere la extensión openssl, trate de Crypt_RSA phpseclib. Ejemplos:

descifrado con PKCS # 1 padding:

openssl rsautl -inkey privatekey.txt-Encrypt -en plaintext.txt salida privado 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')); 
?> 

Cifrado con PKCS # 1 padding:

<?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.tx t -decrypt -en ciphertext.txt salida privado plaintext.txt

descifrado con el acolchado OAEP:

openssl rsautl -inkey privatekey.txt-Encrypt -oaep -en plaintext.txt salida privado texto cifrado.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')); 
?> 

cifrado con el acolchado 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 -en ciphertext.txt salida privado plaintext.txt

phpseclib puede ser descargado de http://phpseclib.sourceforge.net/

¡Buena suerte!

+0

Esto es bueno, pero recomiendo encarecidamente OAEP y nunca utilice el relleno PKCS1, debido a los ataques de oráculo de relleno. –

Cuestiones relacionadas