Quiero cifrar la contraseña usando CryptoJS y C#. Desafortunadamente, mi código C# no genera el valor adecuado. este es mi codigo
internal static byte[] ComputeSha256(this byte[] value) { using (SHA256 sha256Hash = SHA256.Create()) return sha256Hash.ComputeHash(value); } internal static byte[] ComputeSha256(this string value) => ComputeSha256(Encoding.UTF8.GetBytes(value)); internal static byte[] ComputeMD5(this byte[] value) { using (MD5 md5 = MD5.Create()) return md5.ComputeHash(value); } internal static byte[] ComputeMD5(this string value) => ComputeMD5(Encoding.UTF8.GetBytes(value)); internal static byte[] CombineByteArray(byte[] first, byte[] second) { byte[] bytes = new byte[first.Length + second.Length]; Buffer.BlockCopy(first, 0, bytes, 0, first.Length); Buffer.BlockCopy(second, 0, bytes, first.Length, second.Length); return bytes; } internal static string EncryptPassword() { using (AesManaged aes = new AesManaged()) { //CLIENT SIDE PASSWORD HASH /* var password = '12345'; var passwordMd5 = CryptoJS.MD5(password); var passwordKey = CryptoJS.SHA256(CryptoJS.SHA256(passwordMd5 + '12345678') + '01234567890123456'); var encryptedPassword = CryptoJS.AES.encrypt(passwordMd5, passwordKey, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding }); encryptedPassword = CryptoJS.enc.Base64.parse(encryptedPassword.toString()).toString(CryptoJS.enc.Hex); //encryptedPassword result is c3de82e9e8a28a4caded8c2ef0d49c80 */ var y1 = Encoding.UTF8.GetBytes("12345678"); var y2 = Encoding.UTF8.GetBytes("01234567890123456"); var password = "12345"; var passwordMd5 = ComputeMD5(password); var xkey = CombineByteArray(ComputeSha256(CombineByteArray(passwordMd5, y1)), y2); var passwordKey = ComputeSha256(xkey); aes.Key = passwordKey; aes.Mode = CipherMode.ECB; aes.Padding = PaddingMode.None; ICryptoTransform crypt = aes.CreateEncryptor(); byte[] cipher = crypt.TransformFinalBlock(passwordMd5, 0, passwordMd5.Length); var encryptedPassword = BitConverter.ToString(cipher).Replace("-", "").ToLower(); return encryptedPassword; //e969b60e87339625c32f805f17e6f993 } } El resultado del código C# anterior es e969b60e87339625c32f805f17e6f993 . Debería ser lo mismo con CryptoJS c3de82e9e8a28a4caded8c2ef0d49c80 . ¿Que esta mal aquí?
En el código CryptoJS, se agregan hashes (en forma de WordArray s) y cadenas en varios lugares. Por lo tanto, WordArray se codifica implícitamente con toString() en una cadena hexadecimal con letras minúsculas. Esto falta en el código C#.
En el código C#, la adición se realiza con CombineByteArray() , donde el hash se pasa first en el parámetro como byte[] . Por lo tanto, este parámetro debe convertirse primero en una cadena codificada en hexadecimal con letras minúsculas y luego codificarse en UTF8, por ejemplo:
internal static byte[] CombineByteArray(byte[] first, byte[] second) { // Hex encode (with lowercase letters) and Utf8 encode string hex = ByteArrayToString(first).ToLower(); first = Encoding.UTF8.GetBytes(hex); byte[] bytes = new byte[first.Length + second.Length]; Buffer.BlockCopy(first, 0, bytes, 0, first.Length); Buffer.BlockCopy(second, 0, bytes, first.Length, second.Length); return bytes; } donde ByteArrayToString() es de aquí .
Con este cambio, el código C# da el mismo resultado que el código CryptoJS.
No tengo muy claro el propósito del código CryptoJS. Por lo general, el texto sin formato y la clave son independientes, es decir, no se derivan de la misma contraseña.
Quizás se supone que esto implementa una función personalizada de derivación de clave basada en contraseña. Si es así, y a menos que sea obligatoria una implementación personalizada por razones de compatibilidad, es más seguro usar un algoritmo probado como Argon2 o PBKDF2. En particular, la falta de un factor sal/trabajo es insegura.