oaep - encriptacion aes c#
"El relleno no es vĂ¡lido y no se puede eliminar" con AesManaged (4)
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);
}
}
byte [] rawData = new byte [rawPlaintext.Length];
Necesitas leer la longitud del buffer, que probablemente incluya el relleno necesario (IIRC, hace unos años).
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 Mode 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.
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.