2011-06-23 21 views
6

Necesito transferir archivos xml y se requiere que estén encriptados. He encontrado algunos ejemplos que piensan que estoy cerca, pero cuando descifro el archivo termino con caracteres basura. Hay algunas publicaciones sobre esto, pero no he visto ninguna que ayude exactamente. Aquí está el código de cifrado y descifrado.Uso de Rijndael para cifrar/descifrar archivos

private void EncryptFile(string inputFile, string outputFile, string key) { 
    try { 
     byte[] keyBytes; 
     keyBytes = Encoding.Unicode.GetBytes(key); 

     Rfc2898DeriveBytes derivedKey = new Rfc2898DeriveBytes(key, keyBytes); 

     RijndaelManaged rijndaelCSP = new RijndaelManaged(); 
     rijndaelCSP.Key = derivedKey.GetBytes(rijndaelCSP.KeySize/8); 
     rijndaelCSP.IV = derivedKey.GetBytes(rijndaelCSP.BlockSize/8); 

     ICryptoTransform encryptor = rijndaelCSP.CreateEncryptor(); 

     FileStream inputFileStream = new FileStream(inputFile, FileMode.Open, FileAccess.Read); 

     byte[] inputFileData = new byte[(int)inputFileStream.Length]; 
     inputFileStream.Read(inputFileData, 0, (int)inputFileStream.Length); 

     FileStream outputFileStream = new FileStream(outputFile, FileMode.Create, FileAccess.Write); 

     CryptoStream encryptStream = new CryptoStream(outputFileStream, encryptor, CryptoStreamMode.Write); 
     encryptStream.Write(inputFileData, 0, (int)inputFileStream.Length); 
     encryptStream.FlushFinalBlock(); 

     rijndaelCSP.Clear(); 
     encryptStream.Close(); 
     inputFileStream.Close(); 
     outputFileStream.Close(); 
    } 
    catch (Exception ex) { 
     MessageBox.Show(ex.Message, "Encryption Failed!", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     return; 
    } 

    MessageBox.Show("File Encryption Complete!"); 

} 

private void DecryptFile(string inputFile, string outputFile, string key) { 
    try { 
     byte[] keyBytes = Encoding.Unicode.GetBytes(key); 

     Rfc2898DeriveBytes derivedKey = new Rfc2898DeriveBytes(key, keyBytes); 

     RijndaelManaged rijndaelCSP = new RijndaelManaged(); 
     rijndaelCSP.Key = derivedKey.GetBytes(rijndaelCSP.KeySize/8); 
     rijndaelCSP.IV = derivedKey.GetBytes(rijndaelCSP.BlockSize/8); 
     ICryptoTransform decryptor = rijndaelCSP.CreateDecryptor(); 

     FileStream inputFileStream = new FileStream(inputFile, FileMode.Open, FileAccess.Read); 

     CryptoStream decryptStream = new CryptoStream(inputFileStream, decryptor, CryptoStreamMode.Read); 

     byte[] inputFileData = new byte[(int)inputFileStream.Length]; 
     decryptStream.Read(inputFileData, 0, (int)inputFileStream.Length); 

     FileStream outputFileStream = new FileStream(outputFile, FileMode.Create, FileAccess.Write); 
     outputFileStream.Write(inputFileData, 0, inputFileData.Length); 
     outputFileStream.Flush(); 

     rijndaelCSP.Clear(); 

     decryptStream.Close(); 
     inputFileStream.Close(); 
     outputFileStream.Close(); 
    } 
    catch (Exception ex) { 
     MessageBox.Show(ex.Message, "Decryption Failed!", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     return; 
    } 

    MessageBox.Show("File Decryption Complete!"); 
} 

termino con

<?xml version="1.0" encoding="UTF-8"?> 
<transaction> 
    <header> 
    <qOrderNumber></qOrderNumber> 
    <qRequestDate></qRequestDate> 
    <testOrder></testOrder> 
    <qCustomerNumber></qCustomerNumber> 
    <transactionStatus></transactionStatus> 
    </header> 
    <lines> 
    <line> 
     <productID></productID> 
     <serialNumber></serialNumber> 
    </line> 
    <line> 
     <productID></productID> 
     <serialNumber></serialNumber> 
    </line> 
    </lines> 
</transaction>NULNULNULNULNULNUL 

Respuesta

10

Al descifrar, preste atención al valor de retorno de la llamada CryptoStream.Read. Te dice la longitud de los datos descifrados en tu matriz de bytes (por lo general, no coincidirá con la longitud de los datos cifrados debido al relleno). Intente utilizar lo siguiente en su función de descifrado:

int decrypt_length = decryptStream.Read(inputFileData, 0, (int)inputFileStream.Length); 
FileStream outputFileStream = new FileStream(outputFile, FileMode.Create, FileAccess.Write); 
outputFileStream.Write(inputFileData, 0, decrypt_length); 
+0

Y tenemos un ganador !!!! Muchas gracias hermano! – mjames

2

En el objeto de RijndaelManaged, establezca la propiedad Padding a PaddingMode.ANSIX923 o PaddingMode.ISO10126.

Esos bytes nulos se agregaron para completar el último bloque cifrado. Fue rellenado con ceros por defecto, lo que significa que no se proporciona ninguna indicación sobre la longitud real de los datos. Los otros modos de relleno incluyen una longitud en el byte final, por lo que el relleno se puede eliminar después del descifrado.

Establezca la propiedad de relleno en las rutinas de cifrado y descifrado con el mismo valor.

rijndaelCSP.Padding = PaddingMode.ANSIX923; 

Si se sabe que esperar, entonces la corriente de descifrado se retire el relleno de forma automática, por lo que no hay más cambios deberían ser necesarios.

ACTUALIZACIÓN

De su análisis de su código, se observa que el número de bytes que se está escribiendo en el fichero de salida es igual al número de bytes leídos desde el archivo de entrada.

byte[] inputFileData = new byte[(int)inputFileStream.Length]; 
decryptStream.Read(inputFileData, 0, (int)inputFileStream.Length); 

El proceso de descifrado no va a llenar por completo la matriz inputFileData, debido a la relleno en la entrada.

El flujo de salida escribirá la longitud total del búfer, aunque no se haya llenado por completo.

outputFileStream.Write(inputFileData, 0, inputFileData.Length); 

Esta es la fuente de sus valores nulos.

Es posible que desee cambiar la forma en que realiza el cifrado y el descifrado para que ya no utilice bufferes de longitud fija. Alternativamente, puede almacenar la longitud de los datos cifrados al principio, y solo escribir el número de bytes que corresponden a esa longitud.

+0

+1 Me he encontrado con esto en el pasado. Creo que esta es la solución que utilicé para solucionarlo. –

+0

Intenté ambos modos de relleno y obtuve el mismo resultado. – mjames

Cuestiones relacionadas