Este es el ejemplo que he ejecutado. Tiene el mismo Modo, Relleno, Tamaño de bloque, Tamaño de tecla. Estoy usando el mismo vector init, clave y datos.¿Por qué RijndaelManaged y AesCryptoServiceProvider devuelven resultados diferentes?
Uso de la RijndaelManaged produce un valor cifrado de: 0x8d, 0x81,0x27,0xc6,0x3c, 0xe2,0x53,0x2f, 0x35,0x78,0x90,0xc2,0x2e, 0x3B, 0x8A, 0x61, 0x41,0x47 , 0xd6,0xd0,0xff, 0x92,0x72,0x3d, 0xc6,0x16,0x2b, 0xd8,0xb5,0xd9,0x12,0x85
Uso de la AesCryptoServiceProvider produce un valor cifrado de: 0x8d, 0x9f, 0x6e, 0x99, 0xe9,0x54,0x8b, 0x12,0xa9,0x88,0x1a, 0x3d, 0x65,0x23,0x9c, 0x4e, 0x18,0x5a, 0x89,0x31,0xf5,0x75,0xc5,0x9e, 0x0d, 0x43,0xe9,0x86,0xd4 , 0xf3,0x64,0x3a
Aquí está el código que utilicé para generar estos resultados
public partial class AesTest
{
private SymmetricAlgorithm mEncryptionType;
private byte[] mPrivateKey;
private byte[] mInitializationVector;
private byte[] mData;
public AesTest()
{
mPrivateKey = new byte[32]
{
0x22, 0x22, 0x22, 0x22,
0x22, 0x22, 0x22, 0x22,
0x22, 0x22, 0x22, 0x22,
0x22, 0x22, 0x22, 0x22,
0x22, 0x22, 0x22, 0x22,
0x22, 0x22, 0x22, 0x22,
0x22, 0x22, 0x22, 0x22,
0x22, 0x22, 0x22, 0x22
};
mInitializationVector = new byte[16]
{
0x33, 0x33, 0x33, 0x33,
0x33, 0x33, 0x33, 0x33,
0x33, 0x33, 0x33, 0x33,
0x33, 0x33, 0x33, 0x33
};
mData = new byte[16]
{
0x44, 0x44, 0x44, 0x44,
0x44, 0x44, 0x44, 0x44,
0x44, 0x44, 0x44, 0x44,
0x44, 0x44, 0x44, 0x44
};
mEncryptionType = new RijndaelManaged();
mEncryptionType.Mode = CipherMode.CFB;
mEncryptionType.Padding = PaddingMode.PKCS7;
mEncryptionType.BlockSize = 128;
mEncryptionType.KeySize = 256;
byte[] rij_encrypted_data = Encrypt(mData);
mEncryptionType = new AesCryptoServiceProvider();
mEncryptionType.Mode = CipherMode.CFB;
mEncryptionType.Padding = PaddingMode.PKCS7;
mEncryptionType.BlockSize = 128;
mEncryptionType.KeySize = 256;
byte[] aes_encrypted_data = Encrypt(mData);
}
public virtual byte[] Encrypt(byte[] unencryptedData)
{
return TransformData(unencryptedData, mEncryptionType.CreateEncryptor(mPrivateKey, mInitializationVector));
}
private byte[] TransformData(byte[] dataToTransform, ICryptoTransform cryptoTransform)
{
byte[] result = new byte[0];
if (dataToTransform != null && cryptoTransform != null && dataToTransform.Length > 0)
{
// Create the memory stream to store the results
MemoryStream mem_stream = new MemoryStream();
// Create the crypto stream to do the transformation
CryptoStream crypto_stream = new CryptoStream(mem_stream, cryptoTransform, CryptoStreamMode.Write);
// bytes are transformed on a write
crypto_stream.Write(dataToTransform, 0, dataToTransform.Length);
// Flush the final block
crypto_stream.FlushFinalBlock();
// Convert the transformed memory stream back to a byte array
result = mem_stream.ToArray();
// Close the streams
mem_stream.Close();
crypto_stream.Close();
}
return result;
}
}
Supongo que me pregunto si me he perdido algo.
Actualización: Resulta que AesManaged arrojará un CryptographicException ("El modo de cifrado especificado no es válido para este algoritmo") si intenta establecer el CipherMode a CFB. Siento que el AesCryptoServiceProvider debería hacer lo mismo, pero no es así. Parece divertido que la clase certificada por FIPS permita modos de cifrado no válidos.
Esta pregunta salió de la discusión de: http://stackoverflow.com/questions/939040/when-will-c-aes-algorithm-be-fips-compliant –