Porting C# AES Encryption to Javascript for Node.js - javascript

Looking for help to port below C# code into Node.js using crypto or equivalent module.
private string password="FlU4c8yQKLkYuFwsgyU4LFeIf7m3Qwy+poMBdULEMqw=";
private byte[] salt = Encoding.ASCII.GetBytes("##oEDA102ExChAnGe99#$#");
Aes encryptor = Aes.Create();
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, salt);
string pdbStr = Convert.ToBase64String(pdb.GetBytes(32));
Console.WriteLine(pdbStr);
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
Tried porting into javascript as below, but the resulted value are not the same.
var password = "FlU4c8yQKLkYuFwsgyU4LFeIf7m3Qwy+poMBdULEMqw=";
var salt = "##oEDA102ExChAnGe99#$#";
var pdbBytes = crypto.pbkdf2Sync(Buffer.from(password, 'base64'), new Buffer(salt, 'base64'), 1000, 32);
var pdbStr = new Buffer(pdbBytes).toString('base64')
console.log("pdbStr", pdbStr);
Console output:
C# - GZlqgdLbMQ753dTmx1nlJ6HgdabTjW1CeCSoIYkLM4E=
JS - tuDsZJEEwxyXP7RvuYVxGmDy20AvMJAqkLoXX78sEU8=
Any help is much appreciated. Thanks.

these codes parts are generating same the result.
but i did not get 'GZlqgdLbMQ753dTmx1nlJ6HgdabTjW1CeCSoIYkLM4E=' result from c#.
c#
byte[] password= Convert.FromBase64String("FlU4c8yQKLkYuFwsgyU4LFeIf7m3Qwy+poMBdULEMqw=");
byte[] salt = Encoding.ASCII.GetBytes("##oEDA102ExChAnGe99#$#");
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password,salt,1000);
string pdbStr =Convert.ToBase64String(pdb.GetBytes(32));
Console.WriteLine(pdbStr);
//outpu : RMqDMSV6d8uT2NicGM212r3KMFt7ZsOI2q8+0Rr0WZQ=
JS
var crypto = require("crypto");
var password = "FlU4c8yQKLkYuFwsgyU4LFeIf7m3Qwy+poMBdULEMqw=";
var salt = "##oEDA102ExChAnGe99#$#";
crypto.DEFAULT_ENCODING = 'base64';
var pdbBytes = crypto.pbkdf2Sync(new Buffer(password,'base64'), salt, 1000, 32,'sha1');
var pdbStr = new Buffer(pdbBytes).toString()
console.log("pdbStr", pdbStr);
//outpu : RMqDMSV6d8uT2NicGM212r3KMFt7ZsOI2q8+0Rr0WZQ=

Related

TripleDES encryption - c# and javascript differences

I have data encrypted in c#, and need to put together a demo of how to decrypt in javascript. (Note, this is just for a demo - we will not be putting keys into client side code!)
I cannot get the settings right using Crypto-js - I've tried lots of variations, but am getting nowhere.
I cannot change the c# code, so need to get the javascript to work the same way.
Current skeleton code is as follows -
C# (encrypt)
var EncryptionKey = Encoding.ASCII.GetBytes("14ggh11dd3fvv4n4aabb33a3");
var IV = Encoding.ASCII.GetBytes("312a44de");
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Key = EncryptionKey;
tdes.IV = IV;
byte[] buffer = Encoding.ASCII.GetBytes("test");
var ciphertext = Convert.ToBase64String(tdes.CreateEncryptor().TransformFinalBlock(buffer, 0, buffer.Length));
Console.WriteLine(HttpUtility.UrlEncode(ciphertext));
which generates the cipher VrB1Ih0Ll%2fQ%3d
javascript (decrypt)
function decryptByDESModeCBC(ciphertext) {
var key = '14ggh11dd3fvv4n4aabb33a3';
var iv = '312a44de'
ciphertext = decodeURIComponent(ciphertext);
var keyBytes = CryptoJS.enc.Utf8.parse(key);
var ivBytes = CryptoJS.enc.Utf8.parse(iv);
var decrypted = CryptoJS.DES.decrypt({
ciphertext: CryptoJS.enc.Base64.parse(ciphertext)
}, keyBytes, {
iv:ivBytes,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
function test()
{
console.log(decryptByDESModeCBC("VrB1Ih0Ll%2fQ%3d"));
}
Expected result is "test", but I am getting blank.
Any pointers would be great.
As answered by #Topaco in the comments
I needed to use CryptoJS.TripleDES instead of CryptoJS.DES

Using CryptoJS to encrypt and Aes Manager to decrypt

I am using CryptoJS to encrypt a message and send it to the server, and decrypting it on the other end in C# using Aes Manager. I get a response back when I send it to the server, but it isn't correct.
Javascript:
this.CryptoJS=require("crypto-js");
var temp=this.CryptoJS.AES.encrypt("hello","yyyyyyyyyyyyyyyyyyyyyyyyyyyyykey",{
keySize:128/8,
iv:this.CryptoJS.enc.Utf8.parse("helllooohelllooo"),
mode:this.CryptoJS.mode.CBC,
padding:this.CryptoJS.pad.ZeroPadding
});
data.text=temp.toString(); // This is how I send it to the server
C#:
byte[] Key = UTF8Encoding.UTF8.GetBytes("yyyyyyyyyyyyyyyyyyyyyyyyyyyyykey");
byte[] toBytes = UTF8Encoding.UTF8.GetBytes("helllooohelllooo");
AesManaged aes = new AesManaged();
aes.Key = Key;
aes.IV = toBytes;
aes.Padding = PaddingMode.Zeros;
aes.Mode = CipherMode.CBC;
aes.KeySize = 128;
aes.BlockSize = 128;
byte[] bytes = Convert.FromBase64String(data.text);
UTF8Encoding utf8 = new UTF8Encoding();
using (ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
{
MemoryStream MS = new MemoryStream(bytes);
CryptoStream CS = new CryptoStream(MS, decryptor, CryptoStreamMode.Write);
CS.Write(bytes, 0, bytes.Length);
CS.FlushFinalBlock();
MS.Position = 0;
bytes = new byte[MS.Length];
MS.Read(bytes, 0, bytes.Length);
Plaintext = utf8.GetString(bytes);
var temp = 5;
}
This is what I get as a result from the Plaintext variable: t�k�\a``\u007f������\f^,F~\u0017�\u001fp��#5�\u007f\\
You should explicitly pass the key, plaintext and IV as binary data rather than strings:
let iv = CryptoJS.enc.Utf8.parse("helllooohelllooo");
let pt = CryptoJS.enc.Utf8.parse("hello");
let key = CryptoJS.enc.Utf8.parse("yyyyyyyyyyyyyyyyyyyyyyyyyyyyykey");
Then use in the code like so:
CryptoJS.AES.encrypt(pt, key, ...);
Note that your use of zero padding, fixed IV, and no HMAC or AEAD mode makes the code you have completely insecure. You definitely should not use it. Consult this GitHub repository for examples of secure encryption between JavaScript and C#.
I was able to fix my problem i was not converting the original key to utf8 and once i did that it fixed itself
Resource

Encrypt string with Blowfish in NodeJS

I need to encrypt a string but I almost get the output I desire, I read online that it has something to do with padding and iv_vector at the end to complete for the remaining 8 bytes to be same length as txtToEncrypt.
I'm using this library https://github.com/agorlov/javascript-blowfish
// function in Java that I need
// javax.crypto.Cipher.getInstance("Blowfish/CBC/NoPadding").doFinal("spamshog")
var iv_vector = "2278dc9wf_178703";
var txtToEncrypt = "spamshog";
var bf = new Blowfish("spamshog", "cbc");
var encrypted = bf.encrypt(txtToEncrypt, iv_vector);
console.log(bf.base64Encode(encrypted));
Actual output: /z9/n0FzBJQ=
What I need: /z9/n0FzBJRGS6nPXso5TQ==
If anyone has any clue please let me know. I searched all over Google all day.
Finally, here is how to encrypt a string in NodeJS with Blowfish
// Module crypto already included in NodeJS
var crypto = require('crypto');
var iv = "spamshog";
var key = "spamshog";
var text = "2278dc9wf_178703";
var decipher = crypto.createCipheriv('bf-cbc', key, iv);
decipher.setAutoPadding(false);
var encrypted = decipher.update(text, 'utf-8', "base64");
encrypted += decipher.final('base64');
console.log(encrypted);
Returns: /z9/n0FzBJRGS6nPXso5TQ==

Javascript encryption in Crypto decryption in CryptoJS

I'm trying to encrypt server side (crypto Node) and decrypt client side (CryptoJS). I can create the key using cryptoJS, and can encrypt and decrypt when the same individual library is used however the issue is I cannot encrypt with Crypto but decrypt with CryptoJS, which is the real world scenario. There are no errors, just an empty response.
Any help greatly appreciated please!
iv = crypto.randomBytes(16),
orig = 'A confidential message.';
//Crypto JS creates key
var password = "sixteen byte key";
var salt = CryptoJS.lib.WordArray.random(128/8);
var key = CryptoJS.PBKDF2(password, salt, { keySize: 128 / 32, iterations: 1000 });
console.log("step1 generated key: "+ key);
//Convert key for crypto use - as a Buffer
var hashHex = key.toString(CryptoJS.enc.Hex);
var hash = new Buffer(hashHex,'hex');
//Test encryption and decryption with crypto (Node)
//use CryptoJS key to encrypt data using crypto cipheriv
var cipher2 = crypto.createCipheriv('aes-128-cbc', hash, iv); //iv must be a buffer
var encrypted1 = cipher2.update(orig, 'utf8', 'hex');
var encrypted2 = encrypted1 += cipher2.final('hex');
console.log("Crypto string:", encrypted2.toString());
// Start decrypt
var decipher = crypto.createDecipheriv('aes-128-cbc', hash, iv);
var dec = decipher.update(encrypted2, 'hex', 'utf8')
dec += decipher.final('utf8');
console.log("Crypto decrypted msg:", dec);
//test with crypto JS (ie the client)
//CryptoJS key is a string
var encryptedCJS = CryptoJS.AES.encrypt(orig, key.toString(), { iv: iv, mode: CryptoJS.mode.CBC});
console.log("CryptoJS encrypted: "+encryptedCJS);
var decryptedCryptoJS = CryptoJS.AES.decrypt(encryptedCJS, key.toString(), { mode: CryptoJS.mode.CBC, iv: iv });
console.log("CryptoJS decrypted msg: "+decryptedCryptoJS.toString(CryptoJS.enc.Utf8));
//This part does not work - use message encrypted by crypto but cannot decrypt with CryptoJS. decryptedCryptoJSFinal is empty
var decryptedCryptoJSFinal = CryptoJS.AES.decrypt(encrypted2, key.toString(), {iv: iv, mode: CryptoJS.mode.CBC});
console.log("FINAL CryptoJS decrypted: "+decryptedCryptoJSFinal.toString(CryptoJS.enc.Utf8));
I think the output of crypto encryption must be a different format to output of CryptoJS encryption but I cannot find the issue.
Overall I then intend to send the encrypted data as JSON for decryption on the client by CryptoJS.
I think your problem is in the client, if you pass the 'key' and the 'iv' as strings into 'CryptoJS.AES.encrypt', then CryptoJS takes your 'key' and a random 'salt' and generates a different secret key for the cipher. You can verify it generating different cipherTexts from the same clearText with the same key and iv, they will always be different, because a different secret key is generated inside CryptoJS each time you run the function.
To avoid this you need to pass the 'key' and 'iv' encoded (in 'hex' or 'base64' depending in the code you use) and then CryptoJS interprets that it doesn't have to generate a secret key and takes your 'key' to cipher.
Check this example:
//BACKEND with node crypto aes-256-cbc-> generate key and ciphertext
/////////////////////////////////////////////////////////////////////
var crypto = require('crypto');
var algorithm = 'aes-256-cbc';
var inputEncoding = 'utf8';
var outputEncoding = 'base64';
var pt = 'HELLO';
//generate key and iv
var masterKey = "253D3FB468A0E24677C28A624BE0F939";
var salt = "0000000000000000";
var keySize = 256/8;
var ivSize = 128/8;
var iterations = 100;
var outputKey = crypto.pbkdf2Sync(masterKey, salt, iterations, keySize+ivSize, "sha1");
// obtain key and IV splitting outputKey
var buffer = new Buffer(outputKey, inputEncoding);
var secretKey = buffer.slice(0, keySize);
var iv = buffer.slice(keySize, (keySize+ivSize));
console.log('secretKey->',secretKey.toString('base64'));
console.log('iv->',iv.toString('base64'));
//encrypt
var encrypt = crypto.createCipheriv(algorithm, secretKey, iv);
var encrypted = encrypt.update(pt, inputEncoding, outputEncoding);
encrypted += encrypt.final(outputEncoding);
console.log('Ciphering "%s"', pt);
//We obtain a
console.log('CipherText base64' string "%s ', encrypted.toString());
//FRONTEND with node CryptoJS aes-256-cbc-> generate same key and obtain cleartext
////////////////////////////////////////////////////////////////////
var masterKey = "253D3FB468A0E24677C28A624BE0F939";
var salt ="0000000000000000";
var iterations = 100;
var keySize = 256;
var ivSize = 128;
var outputKey = CryptoJS.PBKDF2(masterKey, salt, {
keySize: (keySize+ivSize)/32,
iterations: iterations
});
// the underlying words arrays might have more content than was asked: remove insignificant words
outputKey.clamp();
// split key and IV
var secretKey = CryptoJS.lib.WordArray.create(outputKey.words.slice(0,
keySize/32));
var iv = CryptoJS.lib.WordArray.create(outputKey.words.slice(keySize/32));
console.log('secretKey->', secretKey.toString(CryptoJS.enc.Base64));
console.log('iv->', iv.toString(CryptoJS.enc.Base64));
var decrypted = CryptoJS.AES.decrypt(ct, secretKey,{iv: iv});//Default mode CBC { mode: CryptoJS.mode.CFB });
console.log('CipherText->', ct);
console.log('ClearText decrypted', decrypted.toString(CryptoJS.enc.Utf8));

Decrypt code , from ruby to js

does anyone know how to translate below ruby script to javascript?
source = ENCRYPTED_STRING
cipher = OpenSSL::Cipher::Cipher.new('AES-128-ECB')
cipher.decrypt
cipher.key = ['SECRET'].pack('H*')
decoded = Base64.decode64(source)
decrypted = cipher.update(decoded) + cipher.final
I'm assuming you want to encrypt a string using "SECRET" as a passphrase.
Here's an example using crypto-js:
source = ENCRYPTED_STRING
var encrypted = CryptoJS.AES.encrypt(source, "SECRET");
http://yijiebuyi.com/blog/13e2ae33082ac12ba4946b033be04bb5.html
problem solved.
function decryption(data, key) {
var iv = "";
var clearEncoding = 'utf8';
var cipherEncoding = 'base64';
var cipherChunks = [];
var decipher = crypto.createDecipheriv('aes-128-ecb', key, iv);
decipher.setAutoPadding(true);
cipherChunks.push(decipher.update(data, cipherEncoding, clearEncoding));
cipherChunks.push(decipher.final(clearEncoding));
return cipherChunks.join('');
}

Categories

Resources