2012-03-11 9 views
7

En primer lugar, solo he escrito el código a continuación con fines académicos. La razón por la que digo esto es porque no estoy poniendo esto en un entorno de producción, y por lo tanto estoy "eludiendo" algunos de los gastos generales que tendría que hacer si fuera así, simplemente necesito poder encriptar/desencriptar una cadena usando el código a continuación. Pude hacerlo un par de veces, pero por alguna razón, comencé a recibir "Datos erróneos de CryptographicException" y no estoy seguro de qué podría estar causando el problema."Bad Data" CryptographicException

private string RSAEncrypt(string value) 
    { 
     byte[] encryptedData = Encoding.Unicode.GetBytes(value); 

     CspParameters cspParams = new CspParameters(); 
     cspParams.KeyContainerName = _rsaContainerName; 
     using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(2048,cspParams)) 
     { 
      encryptedData = RSA.Encrypt(encryptedData, false); 
      return Convert.ToBase64String(encryptedData); 

     } 

    } 



    private string RSADecrypt(string value) 
    { 

     byte[] encryptedData = Encoding.Unicode.GetBytes(value); 

     CspParameters cspParams = new CspParameters(); 
     cspParams.KeyContainerName = _rsaContainerName; 
     using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(2048,cspParams)) 
     { 
      encryptedData = RSA.Decrypt(encryptedData,false); 
      return Convert.ToBase64String(encryptedData); 

     } 
    } 

Solo lanza esta excepción en la llamada a RSADecrypt.

¿Alguna idea? Leí en alguna parte que podría tener que ver con el tamaño esperado de encryptedData que se pasa a RSA.Decrypt.

Gracias }

+0

Uh, ¿cómo está pasando las teclas entre los métodos? –

Respuesta

13
  • convertir el texto plano de ida y vuelta usando una cadena de codificación (es decir Encoding.Unicode).

  • Convierta los datos cifrados hacia adelante y hacia atrás utilizando Base-64 (es decir, Convert.[To/From]Base64String);

De esta manera:

private string RSAEncrypt(string value) 
{ 
    byte[] plaintext = Encoding.Unicode.GetBytes(value); 

    CspParameters cspParams = new CspParameters(); 
    cspParams.KeyContainerName = _rsaContainerName; 
    using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(2048,cspParams)) 
    { 
     byte[] encryptedData = RSA.Encrypt(plaintext, false); 
     return Convert.ToBase64String(encryptedData); 
    } 
} 

private string RSADecrypt(string value) 
{ 
    byte[] encryptedData = Convert.FromBase64String(value); 

    CspParameters cspParams = new CspParameters(); 
    cspParams.KeyContainerName = _rsaContainerName; 
    using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(2048,cspParams)) 
    { 
     byte[] decryptedData = RSA.Decrypt(encryptedData,false); 
     return Encoding.Unicode.GetString(decryptedData); 
    } 
} 
6

http://blogs.msdn.com/b/shawnfa/archive/2005/11/10/491431.aspx

No Ida y vuelta texto cifrado A través de una cadena de codificación

Un error común que la gente hace cuando se utiliza el cifrado administrado clases es que se intenta almacenar la resultado de una operación de cifrado en una cadena mediante el uso de una de las clases de codificación. Que parece tener sentido, ¿verdad? Después de todo, Encoding.ToString() toma un byte [] y lo convierte en una cadena que es exactamente lo que estaban buscando .

...

En cambio, si desea convertir el texto cifrado en una cadena, utilice codificación Base64.

...

Resultados en el código que funciona todo el tiempo, ya que la base 64 de codificación es garantiza que sea capaz de representar con precisión cualquier secuencia de bytes de entrada.

Hay una buena, ejemplo correcto aquí: http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndael.aspx

+0

He visto ese artículo, pero no entiendo cuál es la solución o qué debería cambiar en mi código ... ¿podría ayudarme a señalarlo? – TheJediCowboy

+0

Pero OP utiliza 'ByteConverter.GetString' no' Encoding.ToString' –

+0

@ L.B Su "ByteConverter" es un UnicodeEncoding! – matthewk

1

RSA no está destinado a cifrar objetos de gran tamaño. Obtendrá excepciones si supera el límite de relleno. El límite real se basa en el relleno mismo (utilizando false significa que está utilizando el antiguo PKCS # 1 v1.5 relleno) y la longitud de su clave pública (2048 bits).

La forma correcta de usar RSA con un objeto grande es cifrar el objeto grande con una clave simétrica (p.una clave secreta de 256 bits AES) y cifre esta pequeña clave con su clave pública RSA.

Puede encontrar el código para hacer tales cosas en mi blog.

Cuestiones relacionadas