Los cifrados Node.JS RC2-CBC cifrados y descifrados no coinciden con C #

Tengo un inicio de sesión de cifrado y descifrado existente implementado en C # usando el algoritmo RSC2-cbc usando Clave y IV. Ahora voy a implementar lo mismo en node.js. Así que he escrito el siguiente código para cifrar y descifrar. El problema al que me estoy enfrentando es que la cadena encriptada node.js (chiper) o la cadena encriptada no coinciden con las cadenas encriptadas C #.

Código C # existente

byte[] arrbIV = Encoding.ASCII.GetBytes("dleftaba"); byte[] arrbKey = Encoding.ASCII.GetBytes(Key); byte[] arrbData = Encoding.ASCII.GetBytes(sData); //Text to be encryptrd RC2 oEncryptor = new RC2CryptoServiceProvider(); oEncryptor.Mode = CipherMode.CBC; oEncryptor.Key = arrbKey; oEncryptor.IV = arrbIV; // Create memory stream to store encrypted string MemoryStream oMemoryStream = new MemoryStream(); CryptoStream oCryptoStream = new CryptoStream(oMemoryStream, oEncryptor.CreateEncryptor(), CryptoStreamMode.Write); // Peform the encryption oCryptoStream.Write(arrbData, 0, arrbData.Length); // We have written all the data in the stream and now we can apply padding oCryptoStream.Close(); string sRetVal = Convert.ToBase64String(oMemoryStream.ToArray()); 

Código de node.js equivalente / traducido

 var crypto = require('crypto') var SECRET_KEY = "435353553" var IV = "dleftaba" var ENCODING = 'base64' var text = "My Text" Encryption var cipher = crypto.createCipheriv('rc2-cbc',key, iv) var cryptedPassword = cipher.update(text, 'utf-8', 'base64') cryptedPassword+= cipher.final('base64') Decryption var decipher = crypto.createDecipheriv('rc2-cbc', SECRET_KEY, IV) var decryptedPassword = decipher.update(cryptedPassword, 'base64','utf-8') decryptedPassword += decipher.final('utf-8') Please suggest what is going wrong over here. Why node. js is not resulting into the identical chiper like C#. 

Aunque no es el mismo algoritmo que está utilizando … aquí está mi implementación de referencia en C # … He puesto comentarios sobre lo que debería ser la implementación del nodo … y coincide …

Mi objective en ese momento era mantener el lado .Net compatible con los valores predeterminados del lado del nodo …

Relacionado:

  • Cifrado / descifrado AES256 tanto en NodeJS como en C # (.Net)
  • Descifrando datos cifrados AES256 en .NET de node.js – cómo obtener IV y clave de frase de contraseña
  • ¿Versión C # del método OpenSSL EVP_BytesToKey?
 using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; namespace T1.CoreUtils { public static class CryptoUtility { /* Wanting to stay compatible with NodeJS * https://stackoverflow.com/questions/18502375/aes256-encryption-decryption-in-both-nodejs-and-c-sharp-net/ * https://stackoverflow.com/questions/12261540/decrypting-aes256-encrypted-data-in-net-from-node-js-how-to-obtain-iv-and-key * https://stackoverflow.com/questions/8008253/c-sharp-version-of-openssl-evp-bytestokey-method */ /* EncrypteDefault - as NodeJS * var cipher = crypto.createCipher('aes-256-cbc', 'passphrase'); * var encrypted = cipher.update("test", 'utf8', 'base64') + cipher.final('base64'); */ public static string EncryptDefault(string input, string passphrase = null) { byte[] key, iv; PassphraseToDefaultKeyAndIV(RawBytesFromString(passphrase), null, 1, out key, out iv); return Convert.ToBase64String(EncryptBytes(Encoding.UTF8.GetBytes(input), key, iv)); } /* DecryptDefault - as NodeJS * var decipher = crypto.createDecipher('aes-256-cbc', 'passphrase'); * var plain = decipher.update(encrypted, 'base64', 'utf8') + decipher.final('utf8'); */ public static string DecryptDefault(string inputBase64, string passphrase = null) { byte[] key, iv; PassphraseToDefaultKeyAndIV(RawBytesFromString(passphrase), null, 1, out key, out iv); return Encoding.UTF8.GetString(DecryptBytes(Convert.FromBase64String(inputBase64), key, iv)); } public static string Encrypt(string input, string passphrase = null) { byte[] key, iv; PassphraseToSCryptKeyAndIV(passphrase, out key, out iv); return Convert.ToBase64String(EncryptBytes(Encoding.UTF8.GetBytes(input), key, iv)); } public static string Decrypt(string inputBase64, string passphrase = null) { byte[] key, iv; PassphraseToSCryptKeyAndIV(passphrase, out key, out iv); return Encoding.UTF8.GetString(DecryptBytes(Convert.FromBase64String(inputBase64), key, iv)); } static byte[] RawBytesFromString(string input) { var ret = new List(); foreach (char x in input) { var c = (byte)((ulong)x & 0xFF); ret.Add(c); } return ret.ToArray(); } public static void PassphraseToSCryptKeyAndIV(string passphrase, out byte[] key, out byte[] iv) { var hashList = HashUtility.HashSCrypt(Encoding.UTF8.GetBytes(passphrase)).ToList(); key = new byte[32]; iv = new byte[16]; hashList.CopyTo(0, key, 0, 32); hashList.CopyTo(32, iv, 0, 16); } public static void PassphraseToDefaultKeyAndIV(byte[] data, byte[] salt, int count, out byte[] key, out byte[] iv) { List hashList = new List(); byte[] currentHash = new byte[0]; int preHashLength = data.Length + ((salt != null) ? salt.Length : 0); byte[] preHash = new byte[preHashLength]; System.Buffer.BlockCopy(data, 0, preHash, 0, data.Length); if (salt != null) System.Buffer.BlockCopy(salt, 0, preHash, data.Length, salt.Length); MD5 hash = MD5.Create(); currentHash = hash.ComputeHash(preHash); for (int i = 1; i < count; i++) { currentHash = hash.ComputeHash(currentHash); } hashList.AddRange(currentHash); while (hashList.Count < 48) // for 32-byte key and 16-byte iv { preHashLength = currentHash.Length + data.Length + ((salt != null) ? salt.Length : 0); preHash = new byte[preHashLength]; System.Buffer.BlockCopy(currentHash, 0, preHash, 0, currentHash.Length); System.Buffer.BlockCopy(data, 0, preHash, currentHash.Length, data.Length); if (salt != null) System.Buffer.BlockCopy(salt, 0, preHash, currentHash.Length + data.Length, salt.Length); currentHash = hash.ComputeHash(preHash); for (int i = 1; i < count; i++) { currentHash = hash.ComputeHash(currentHash); } hashList.AddRange(currentHash); } hash.Clear(); key = new byte[32]; iv = new byte[16]; hashList.CopyTo(0, key, 0, 32); hashList.CopyTo(32, iv, 0, 16); } public static byte[] EncryptBytes(byte[] input, byte[] Key, byte[] IV) { // Check arguments. if (input == null || input.Length <= 0) return new byte[0]; //nothing to encode if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key"); if (IV == null || IV.Length <= 0) throw new ArgumentNullException("Key"); // Create an RijndaelManaged object // with the specified key and IV. using (RijndaelManaged cipher = new RijndaelManaged()) { cipher.Key = Key; cipher.IV = IV; cipher.Mode = CipherMode.CBC; cipher.Padding = PaddingMode.PKCS7; // Create a decrytor to perform the stream transform. ICryptoTransform encryptor = cipher.CreateEncryptor(cipher.Key, cipher.IV); // Create the streams used for encryption. using (MemoryStream outputStream = new MemoryStream()) { using (CryptoStream encryptStream = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write)) { encryptStream.Write(input, 0, input.Length); encryptStream.FlushFinalBlock(); outputStream.Seek(0, 0); return outputStream.ToArray(); } } } } public static byte[] DecryptBytes(byte[] cipherText, byte[] Key, byte[] IV) { // Check arguments. if (cipherText == null || cipherText.Length <= 0) throw new ArgumentNullException("cipherText"); if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key"); if (IV == null || IV.Length <= 0) throw new ArgumentNullException("Key"); // Create an RijndaelManaged object // with the specified key and IV. using (var cipher = new RijndaelManaged()) { cipher.Key = Key; cipher.IV = IV; cipher.Mode = CipherMode.CBC; cipher.Padding = PaddingMode.PKCS7; // Create a decrytor to perform the stream transform. ICryptoTransform decryptor = cipher.CreateDecryptor(cipher.Key, cipher.IV); // Create the streams used for decryption. using (var inputStream = new MemoryStream(cipherText)) { using (var outputStream = new MemoryStream()) { using (CryptoStream decryptedStream = new CryptoStream(inputStream, decryptor, CryptoStreamMode.Read)) { var buffer = new byte[1024]; decryptedStream.Flush(); var read = decryptedStream.Read(buffer, 0, buffer.Length); while (read > 0) { outputStream.Write(buffer, 0, read); decryptedStream.Flush(); read = decryptedStream.Read(buffer, 0, buffer.Length); } outputStream.Seek(0, 0); return outputStream.ToArray(); } } } } } } } 

Node.js

 var crypto = require('crypto'); module.exports = { encrypt: encryptValue, decrypt: decryptValue } function encryptValue(input, passphrase) { var cipher = crypto.createCipher('aes-256-cbc', passphrase); var encrypted = cipher.update(input, 'utf8', 'base64') + cipher.final('base64'); return encrypted; } function decryptValue(inputBase64, passphrase) { var decipher = crypto.createDecipher('aes-256-cbc', passphrase); var plain = decipher.update(inputBase64, 'base64', 'utf8') + decipher.final('utf8'); return plain; } 

Mi código .Net hace referencia a HashUtility, que no es estrictamente necesario, y no tengo mi implementación completa de node.js con scrypt disponible … Fue principalmente para probar contra.