2011-11-29 10 views
9

Hasta hoy vivía con la impresión de que el cifrado RSA con RSA es determinista. Después de todo, ¿cómo debería funcionar la verificación de firma si no fuera así?¿Por qué el resultado de RSACryptoServiceProvider.Encrypt() no es estable?

Para mi gran sorpresa, .NETs RSACryptoServiceProvider no tiene una salida estable al cifrar el mismo conjunto de bytes con las mismas claves:

[Fact] 
public void Learning() 
{ 
    const int keySize = 1024; 

    System.Security.Cryptography.RSACryptoServiceProvider rsa = new System.Security.Cryptography.RSACryptoServiceProvider(keySize); 

    var bytes = GenerateRandomDataWithLength(36); 

    for (int i = 0; i < 4; i++) 
     Assert.Equal(rsa.Encrypt(bytes, false), rsa.Encrypt(bytes, false)); 
} 

byte[] GenerateRandomDataWithLength(int length) 
{ 
    Random r = new Random(); 

    byte[] data = new byte[length]; 
    r.NextBytes(data); 

    return data; 
} 

He desnatada a través de la PKCS Specification y me hacen entender las matemáticas detrás de RSA, entonces realmente me pregunto por qué estoy observando que la salida es inestable.

La implementación RSA de Mono tiene una salida estable. La salida inestable de Encrypt no afecta el descifrado, que es muy posible y proporciona los datos esperados.

Respuesta

13

La encriptación RSA es pura matemática por lo que le dará el mismo resultado cada vez. Sin embargo, llamar al Encrypt en .NET no es simplemente hacer encriptación RSA.

¿Por qué? El relleno PKCS # 1 (predeterminado cuando usa false en Encrypt) hará que cada resultado encriptado sea diferente porque incluye datos aleatorios (para fines de relleno).

Mono tiene el mismo comportamiento de (al menos en mi sistema, ver nota). Sin embargo, si está usando EncryptValue, que Mono admite pero .NET no (limitación de CryptoAPI), entonces no se realizará el relleno de y el resultado cifrado será idéntico cada vez.

Nota: Si tiene resultados diferentes, complete un informe de error en http://bugzilla.xamarin.com e incluya el número de versión que está utilizando.

+0

De acuerdo, olvidé por completo los datos aleatorios incluidos. Usted está claramente aquí. ¡Gracias por tu respuesta! (La versión mono a la que me refería era muy antigua, solo eran las fuentes de Monos RSA en realidad). –

+1

@Johannes Tenga en cuenta que se necesita un relleno aleatorio para hacer que el cifrado RSA sea seguro contra los ataques de texto claro elegidos (es decir, encriptar un texto sin formato adivinado de nuevo para ver si el resultado coincide con el interceptado anteriormente). –

+2

Para mayor claridad, agregaría que el uso de 'true' en' Encrypt' también da como resultado un relleno aleatorio, creo ('OAEP'). –

Cuestiones relacionadas