I have a use case where the text has to be encoded and sent using the AES 256 algorithm. The client-side code is in C# which would be decrypting the code.
Encryption code in JS:
const crypto = require('crypto');
algorithm = 'aes-256-cbc',
secret = '1234567890123456',
keystring = crypto.createHash('sha256').update(String(secret)).digest('base64').substr(0, 16);
iv = crypto.createHash('sha256').update(String(secret)).digest('base64').substr(0, 16);
inputEncoding = 'utf8',
outputEncoding = 'base64';
function encrypt(text) {
let cipher = crypto.createCipheriv('aes-256-cbc', keystring, iv);
let encrypted = cipher.update(text, inputEncoding, outputEncoding)
encrypted += cipher.final(outputEncoding);
return encrypted;
}
Updated code used in the client side:
var keybytes = Encoding.UTF8.GetBytes(passwordKey);
var iv = Encoding.UTF8.GetBytes(passwordKey);
private byte[] EncryptStringToBytes(string plainText, byte[] key, byte[] iv)
{
try
{
// Check arguments.
if (plainText == null || plainText.Length <= 0)
{
throw new ArgumentNullException("plainText");
}
if (key == null || key.Length <= 0)
{
throw new ArgumentNullException("key");
}
if (iv == null || iv.Length <= 0)
{
throw new ArgumentNullException("key");
}
byte[] encrypted;
// Create a RijndaelManaged object
// with the specified key and IV.
using (var rijAlg = new RijndaelManaged())
{
rijAlg.Mode = CipherMode.CBC;
rijAlg.Padding = PaddingMode.PKCS7;
rijAlg.FeedbackSize = 128;
rijAlg.Key = key;
rijAlg.IV = iv;
// Create a decrytor to perform the stream transform.
var encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
// Create the streams used for encryption.
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (var swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
// Return the encrypted bytes from the memory stream.
return encrypted;
}
catch (Exception ex)
{
throw ex;
//LoggerCS.logError("Utility", "EncryptStringToBytes", JsonConvert.SerializeObject(null), ex.ToString(), ex.StackTrace);
}
return null;
}
The keyString and IV value used are same in C# and is encrypted using Utf8. Looking for the equivalent operation in Node JS.
The resolution was pretty simple than expected. The RijndaelManaged code with keylen 128 referred to AES-128 algorithm and using aes-128-cbc in nodeJS.
Also, since the C# code used getBytes for key and iv value. Buffer.from(secret) had to be used for both key and iv value in nodeJS. Final solution looks like:
const crypto = require('crypto');
algorithm = "aes-128-cbc",
secret = '1234567890123456',
keystring = new Buffer(secret),
iv = new Buffer(secret),
inputEncoding = 'utf8',
outputEncoding = 'base64';
function encrypt(text) {
let cipher = crypto.createCipheriv(algorithm,keystring, iv);
let encrypted = cipher.update(text, inputEncoding, outputEncoding)
encrypted += cipher.final(outputEncoding);
return encrypted;
}
function decrypt(encrypted) {
let decipher = crypto.createDecipheriv(algorithm,keystring, iv)
let dec = decipher.update(encrypted, outputEncoding, inputEncoding)
dec += decipher.final(inputEncoding);
return dec;
}