“El relleno no es válido y no se puede eliminar” con AesManaged

Estoy intentando que el cifrado / descifrado simple funcione con AesManaged, pero sigo obteniendo una excepción cuando trato de cerrar la secuencia de descifrado. La cadena aquí se cifra y descifra correctamente, y luego aparece CryptographicException “El relleno no era válido y no se puede eliminar” después de Console.WriteLine imprime la cadena correcta.

¿Algunas ideas?

MemoryStream ms = new MemoryStream(); byte[] rawPlaintext = Encoding.Unicode.GetBytes("This is annoying!"); using (Aes aes = new AesManaged()) { aes.Padding = PaddingMode.PKCS7; aes.Key = new byte[128/8]; aes.IV = new byte[128/8]; using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write)) { cs.Write(rawPlaintext, 0, rawPlaintext.Length); cs.FlushFinalBlock(); } ms = new MemoryStream(ms.GetBuffer()); using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Read)) { byte[] rawData = new byte[rawPlaintext.Length]; int len = cs.Read(rawData, 0, rawPlaintext.Length); string s = Encoding.Unicode.GetString(rawData); Console.WriteLine(s); } } 

El truco es usar MemoryStream.ToArray() . También cambié tu código para que use CryptoStream para escribir, tanto en encriptación como en descifrado. Y no necesita llamar a CryptoStream.FlushFinalBlock() explícitamente, porque lo tiene en una instrucción using() , y ese vaciado tendrá lugar en Dispose() . El siguiente funciona para mi.

 byte[] rawPlaintext = System.Text.Encoding.Unicode.GetBytes("This is all clear now!"); using (Aes aes = new AesManaged()) { aes.Padding = PaddingMode.PKCS7; aes.KeySize = 128; // in bits aes.Key = new byte[128/8]; // 16 bytes for 128 bit encryption aes.IV = new byte[128/8]; // AES needs a 16-byte IV // Should set Key and IV here. Good approach: derive them from // a password via Cryptography.Rfc2898DeriveBytes byte[] cipherText= null; byte[] plainText= null; using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write)) { cs.Write(rawPlaintext, 0, rawPlaintext.Length); } cipherText= ms.ToArray(); } using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write)) { cs.Write(cipherText, 0, cipherText.Length); } plainText = ms.ToArray(); } string s = System.Text.Encoding.Unicode.GetString(plainText); Console.WriteLine(s); } 

Además, supongo que sabe que deseará establecer explícitamente el Modo de la instancia AesManaged y usar System.Security.Cryptography.Rfc2898DeriveBytes para derivar la clave y IV de una contraseña y una sal.

ver también:
– AesManaged

Esta excepción puede ser causada por una falta de coincidencia de cualquiera de varios parámetros de encriptación.

Utilicé la interfaz Security.Cryptography.Debug para rastrear todos los parámetros utilizados en los métodos de cifrado / descifrado.

Finalmente descubrí que mi problema era que establecí la propiedad KeySize después de configurar la Key provocó que la clase regenerara una clave aleatoria y no usara la clave que estaba configurada inicialmente.

byte [] rawData = new byte [rawPlaintext.Length];

Necesitas leer la longitud del buffer, que probablemente incluya el relleno necesario (IIRC, hace unos años).

Nadie respondió, que en realidad MemoryStream.GetBuffer devuelve el búfer asignado, no los datos reales en este búfer. En este caso, devuelve un búfer de 256 bytes, mientras que contiene solo 32 bytes de datos cifrados.

Intereting Posts