2009-07-29 132 views
39

Soy nuevo en el cifrado. Necesito implementar un algoritmo de encriptación asimétrico, que creo que usa una clave privada/pública. Empecé a usar una muestra de RSACryptoServiceProvider. estaba bien con pequeños datos para encriptar. ¡Pero cuando lo uso en datos relativamente grandes "2 líneas", obtengo la excepción CryptographicException "Bad Length"!cómo usar RSA para cifrar archivos (datos enormes) en C#

//Create a new instance of RSACryptoServiceProvider. 
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider()) 
{ 

    //Import the RSA Key information. This only needs 
    //toinclude the public key information. 
    //RSA.ImportParameters(RSAKeyInfo); 
    byte[] keyValue = Convert.FromBase64String(publicKey); 
    RSA.ImportCspBlob(keyValue); 

    //Encrypt the passed byte array and specify OAEP padding. 
    //OAEP padding is only available on Microsoft Windows XP or 
    //later. 
    encryptedData = RSA.Encrypt(DataToEncrypt, DoOAEPPadding); 
} 

Entonces me encontré con algunas muestras de cifrado de datos de gran tamaño (o archivos) mediante el uso de CryptoStream, y sólo utilizan algoritmos simétricos como DES o 3DES, que tienen la CreateEncryptor función para devolver ICryptoTransform como una de las entradas al constructor de CryptoStream !!!

CryptoStream cStream = new CryptoStream(fStream, 
       new TripleDESCryptoServiceProvider().CreateEncryptor(Key, IV), 
       CryptoStreamMode.Write); 

¿Cuál es la forma de encriptar archivos utilizando RSA?

+15

Los algoritmos privados/públicos no son adecuados para encriptar datos grandes. En la práctica, se usan para intercambiar una clave secreta privada entre las dos partes que se utilizará para encriptar/descifrar simétricamente los datos de gran tamaño. –

Respuesta

32

Como se ha mencionado en otras respuestas cifrado asimétrico está diseñado únicamente para la encriptación de datos más pequeños de lo que es el tamaño de clave.

Una opción que he implementado cuando necesito transferir grandes cantidades de datos cifrados entre dos sistemas es tener un par de llaves RSA cuya clave pública es conocida tanto por el emisor como por el receptor, cuando los datos deben enviarse el receptor genera un nuevo par de claves RSA, encripta la clave pública de ese par de claves con la clave pública común y envía la clave pública encriptada al remitente. El remitente descifra la clave pública de los receptores usando su clave privada (que el receptor no necesita saber, al igual que el remitente no necesita conocer la clave privada generada por los receptores), genera una clave de cifrado simétrica, encripta los datos con la clave simétrica y luego encripta la clave simétrica usando la clave pública recibida del receptor.Tanto la clave simétrica encriptada como los datos encriptados se envían al receptor que usa su clave privada generada para descifrar la clave simétrica y luego descifra los datos.

Puede usar los métodos RSACryptoServiceProvider.ToXMLString() y RSACryptoServiceProvider.FromXMLString() para almacenar la clave pública común como un literal de cadena XML en la aplicación receptora.

No olvide, cuando genera la clave de cifrado simétrica para usar RNGCryptoServiceProvider() para generar la clave, ya que es un método mucho más seguro para generar números (pseudo) aleatorios.

Además, le recomiendo que no use 3DES como su algoritmo de cifrado simétrico, es antiguo y comienza a mostrar su edad. Utilice el cifrado simétrico AES con las clases AesCryptoServiceProvicer o RijndaelManaged.

19

Normalmente, RSA solo se usa para transferir una clave simétrica (al comienzo de la transmisión, por ejemplo) y luego los datos masivos se cifran con esa clave.

La encriptación asimétrica no es lo suficientemente eficiente como para transferir una gran cantidad de datos.

6

Las implementaciones .NET de RSA (y todos los algoritmos de clave pública/privada) no son compatibles con grandes bloques de datos, porque ese no es el objetivo de la clave pública/privada.

En cambio, lo que haría sería generar una nueva clave simétrica y usarla para cifrar los datos. Luego, usa la clave pública/privada para encriptar la clave simétrica e intercambiarla con la otra parte de forma segura. A continuación, desencriptan la clave simétrica y la utilizan para desencriptar sus datos.

56

RSA sólo se puede cifrar bloques de datos que son más cortas que la longitud de la clave así que lo que lo hace normalmente es

  1. generar una clave aleatoria de la longitud correcta requerida para AES (o similar).
  2. cifrar los datos utilizando AES o similares utilizando esa clave
  3. cifrar la clave aleatoria usando su clave RSA

continuación, publicar tanto las salidas de 2 y 3

Para descifrar

  1. Descifre la tecla AES usando su clave RSA.
  2. descifrar los datos usando esa clave AES
+0

Si hace esto, los únicos que pueden descifrar los datos son aquellos que poseen la clave privada de su par de claves RSA. –

+24

Sí, por supuesto, ¿no es realmente el punto de encriptación? – jcoder

18

Para búsquedas en el futuro con respecto a RSA excepciones mal longitud ...

se puede calcular el número máximo de bytes que pueden ser cifrados con un tamaño de clave particular en lo siguiente:

((keysize - 384)/8) + 37

Sin embargo, si el relleno cifrado asimétrico óptimo (OAEP) parámetro es cierto, se puede utilizar para calcular el bytes max lo siguiente:

((tamaño de clave - 384)/8) + 7

Los tamaños de clave legales 384 thru 16384 con un tamaño de salto de 8.

1

tenemos:

MaxBlockSize=((KeySize - 384)/8) + 37 

O

MaxBlockSize=((KeySize - 384)/8) + 7 

lo tanto, podemos dividir los datos de algunos bloques y luego, cifra cada uno y luego combínalos