Tengo un cifrado AES están realizando en dos columnas: una de estas columnas se almacena en una base de datos SQL Server 2000 ; la otra se almacena en una base de datos SQL Server 2008 .Cómo conseguir la compatibilidad entre C# y cifrado AES SQL2k8?
Como la base de datos de la primera columna (2000) no tiene una funcionalidad nativa para el cifrado/descifrado, hemos decidido hacer la lógica de criptografía a nivel de aplicación, con clases .NET, para ambos. Pero como la base de datos de la segunda columna (2008) permite este tipo de funcionalidad, nos gustaría que la migración de datos usando las funciones de la base de datos sea más rápida, ya que la migración de datos en SQL durará más de 50 horas debido a que se realizó a nivel de aplicación.
Mi problema comenzó en este punto: usando la misma clave, no logré el mismo resultado al encriptar un valor, ni el mismo tamaño de resultado.
A continuación tenemos la lógica completa en ambos lados .. Por supuesto no estoy mostrando la clave, pero todo lo demás es el mismo:
private byte[] RijndaelEncrypt(byte[] clearData, byte[] Key)
{
var memoryStream = new MemoryStream();
Rijndael algorithm = Rijndael.Create();
algorithm.Key = Key;
algorithm.IV = InitializationVector;
var criptoStream = new CryptoStream(memoryStream, algorithm.CreateEncryptor(), CryptoStreamMode.Write);
criptoStream.Write(clearData, 0, clearData.Length);
criptoStream.Close();
byte[] encryptedData = memoryStream.ToArray();
return encryptedData;
}
private byte[] RijndaelDecrypt(byte[] cipherData, byte[] Key)
{
var memoryStream = new MemoryStream();
Rijndael algorithm = Rijndael.Create();
algorithm.Key = Key;
algorithm.IV = InitializationVector;
var criptoStream = new CryptoStream(memoryStream, algorithm.CreateDecryptor(), CryptoStreamMode.Write);
criptoStream.Write(cipherData, 0, cipherData.Length);
criptoStream.Close();
byte[] decryptedData = memoryStream.ToArray();
return decryptedData;
}
Este es el ejemplo de código SQL:
open symmetric key columnKey decryption by password = N'{pwd!!i_ll_not_show_it_here}'
declare @enc varchar(max)
set @enc = dbo.VarBinarytoBase64(EncryptByKey(Key_GUID('columnKey'), 'blablabla'))
select LEN(@enc), @enc
Este varbinaryToBase64 es una función SQL probado que utilizamos para convertir varbinary en el mismo formato que utilizamos para cadenas de tiendas en la aplicación .NET.
El resultado en C# es: eg0wgTeR3noWYgvdmpzTKijkdtTsdvnvKzh + uhyN3Lo =
el mismo resultado en SQL2k8 es: AI0zI7D77EmqgTQrdgMBHAEAAACyACXb + P3HvctA0yBduAuwPS4Ah3AB4Dbdj2KBGC1Dk4b8GEbtXs5fINzvusp8FRBknF15Br2xI1CqP0Qb/M4W
sólo que no entiendo todavía lo que estoy haciendo incorrecto.
¿Tiene alguna idea?
EDIT: Un punto creo que es crucial: Tengo un vector de inicialización en mi código C#, 16 bytes. Este IV no está configurado con la clave simétrica de SQL, ¿podría hacer esto?
Pero aún no llenar el IV en C#, consigo resultados muy diferentes, tanto en su contenido y duración.
¿Hay algo en la documentación que indique que los dos algoritmos de cifrado son de hecho el mismo? – Joe
dicen que ambos son AES, ¿verdad? Pensé que esto sería suficiente para garantizar cierta interoperabilidad. –