I use some remote api, they use such C# code:
SHA256Managed sha256Managed = new SHA256Managed();
byte[] passwordSaltBytes = Encoding.Unicode.GetBytes("zda");
byte[] hash = sha256Managed.ComputeHash(passwordSaltBytes);
string result = Convert.ToBase64String(hash);
Console.WriteLine("result = " + result); // result = NUbWRkT8QfzmDt/2kWaikNOZUXIDt7KKRghv0rTGIp4=
I need to get the same result in my javascript frontend code. Does somebody can help with such problem?
The answer is:
var utf8arr = CryptoJS.enc.Utf16LE.parse("zda");
var hash = CryptoJS.SHA256(utf8arr);
var base64 = CryptoJS.enc.Base64.stringify(hash);
console.log(base64);
Not quite obvious, but Unicode in C# is using UTF-16LE enconding.
So you can use CryptoJS to achieve the same result:
var utf16 = CryptoJS.enc.Utf16LE.parse("zda");
var hash = CryptoJS.SHA256(utf16);
var base64 = CryptoJS.enc.Base64.stringify(hash);
console.log(base64);
Related
I have a requirement where I need to encode data in "iso-8859-1" and then convert back it to readable string in node js.
In .Net env:
string encodedData = "VABpAG0AZQAgAHMAZQByAGUAaQBzAA==";
Encoding encoding = Encoding.GetEncoding("iso-8859-1"); // encoding in "iso-8859-1"
byte[] = decodedbuff = convert.FromBase64String(encodedData); // getting buffer
result = encoding.GetString(decodedbuff); //decoding
result = timesereis
In a similar way, I need to encode and decode in node js
In Node js(using iconvlite)
const data = "VABpAG0AZQAgAHMAZQByAGUAaQBzAA=="
const buffer = iconvlite.encode(data,'iso-8859-1');
const result = buffer.toString('utf8');
Here in result, I am getting "VABpAG0AZQAgAHMAZQByAGUAaQBzAA==" instead of decoded result
By using the following code you get your desired result
let buffer = new Buffer(data, 'base64');
let result = buff.toString('utf-8');
console.log("result: "+text)
In C# I have the following code:
public static string GetHashCode(string p)
{
var a = new SHA256Managed();
return Convert.ToBase64String(a.ComputeHash(new System.Text.UTF8Encoding().GetBytes(p)));
}
And I have to achieve the same thing in Javascript, I was trying the following but it gives different result:
btoa((CryptoJS.SHA256(this.toUTF8Array(this.settingsService.Password)).toString(CryptoJS.enc.Hex)));
What am I supposed to do, what is wrong?
Example output for string 'aaa' for:
C#:1f9e1d76685d765aa3a6ff85dced2f0a04f612536df52696684aaa67787e6cdd
Js:NGVhNWM1MDhhNjU2NmU3NjI0MDU0M2Y4ZmViMDZmZDQ1Nzc3N2JlMzk1NDljNDAxNjQzNmFmZGE2NWQyMzMwZQ==
I'm not that familiar with CryptoJS but I think you are outputting hex which is not the same as base64.
This generates the same result as C# see fiddle
var utf8arr = CryptoJS.enc.Utf8.parse("apassword");
var hash = CryptoJS.SHA256(utf8arr);
var base64 = CryptoJS.enc.Base64.stringify(hash);
console.log(base64);
I am coding in node.js where i want to use AES/ECB/Pkcs5 for encrypting my string with a particular key. Now i have java code which is given below but as i tried to code the same thing in javascript things became really messy, Firstly i saw a simple solution of using crypto whose code is given below and i tried it but the output i got was different from the one i got from java, then i switched from crypto to Crypto-js which is another library for encryption now i gain tried the same but i again got different output and then finally when i saw plethora of posts where one said to declare iv and the other one to use key and input_string as a buffer and the other one to use chunks to encrypt the data.
Now as you can imagine i have tried for two days straight to code all these possibilities but none of them worked out, now can anyone please enlighten me and tell me which is the right approach or where i am missing something.
Thanks
JAVA CODE
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(1, secretKeySpec);
byte[] aBytes = cipher.doFinal(inputString.getBytes());
BASE64Encoder encoder = new BASE64Encoder();
String base64 = encoder.encode(aBytes).toString();
base64 = URLEncoder.encode(base64, "UTF-8");
return base64;
CRYPTO-JS CODE
var encrypted = CryptoJS.DES.encrypt(input_string, key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
var base64 = CryptoJS.enc.Base64.toString(encrypted.ciphertext);
// var base64 = CryptoJS.enc.Base64.stringify(encrypted);
var parsedStr = base64.toString(CryptoJS.enc.Utf8);
console.log('parsedStr: ', parsedStr);
Crypto CODE
var cipher = crypto.createCipher('aes-128-ecb', key);
var crypted = cipher.update(input_string,'utf8','base64')
crypted += cipher.final('base64');
Chunks Implementation
var crypto = require('crypto'),
iv = new Buffer(''),
key = new Buffer('abcgthdbgfhyjhuy', 'hex'),
cipher = cypto.createCipheriv('aes-128-ecb', key, iv),
chunks = [];
chunks.push(cipher.update(
new Buffer(JSON.stringify({key: "abcgthdbgfhyjhuy"}), 'utf8'),
'buffer', 'base64'));
chunks.push(cipher.final('base64'));
var encryptedString = chunks.join('');
console.log('encryptedString: ', encryptedString);
ONE WHERE I USED input_string AND key AS BUFFER
var key = new Buffer(key, "utf8");
var input_string = new Buffer(input_string, "utf8");
IV USAGE
var key = new Buffer(key, "utf8");
var input_string = new Buffer(input_string, "utf8");
var iv = new Buffer(16); // 16 byte buffer with random data
iv.fill(0); // fill with zeros
var cipher = crypto.createCipher('aes-128-ecb', key, iv);
var crypted = cipher.update(input_string,'utf8','base64')
crypted += cipher.final('base64');
My code
I'm encrypting a string with two different keys with CryptoJS:
var password = "testpassword";
var serverkey = "randomkey";
var text = document.getElementById("new_note").value;
var encrypted1 = CryptoJS.AES.encrypt(text, password);
encrypted1 = encrypted1.toString();
var encrypted = CryptoJS.AES.encrypt(encrypted1,serverkey);
And trying to decrypt it with this code:
var password = "testpassword";
var serverkey = "randomkey";
var encrypted_text = localStorage.getItem("encrypted");
var decrypted1 = CryptoJS.AES.decrypt(encrypted_text,serverkey);
decrypted1 = decrypted.toString();
var decrypted = CryptoJS.AES.decrypt(decrypted1,password);
decrypted = decrypted.toString(CryptoJS.enc.Utf8);
document.getElementById("decrypted").innerHTML = decrypted;
What isn't working
While the encryption seems to work fine, when I try to convert decrypted1 to a string in order to decrypt it the second time, I get Cannot read property 'toString' of undefined on the chrome console. This should mean that the first decryption process returns an empty string.
My question
How can I fix this problem?
There is a typo in your variable names. Check where you define decrypted and where you use it. You meant to use decrypted1.
Additionally, you have a problem with the encoding. The first decrypted1.toString(); will encode the string into Hex, but earlier you called encrypted1.toString(); which does not encode to Hex, but a special Base64 encoding (OpenSSL compatible). You will need to encode to UTF-8 in order to get to the same encoding that you had before during encryption.
Here is the working code:
document.getElementById("enc_button").onclick = function(){
var password = "testpassword";
var serverkey = "randomkey";
var text = document.getElementById("new_note").value;
var encrypted1 = CryptoJS.AES.encrypt(text, password);
encrypted1 = encrypted1.toString();
var encrypted = CryptoJS.AES.encrypt(encrypted1, serverkey);
var decrypted1 = CryptoJS.AES.decrypt(encrypted,serverkey);
decrypted1 = decrypted1.toString(CryptoJS.enc.Utf8);
var decrypted = CryptoJS.AES.decrypt(decrypted1,password);
decrypted = decrypted.toString(CryptoJS.enc.Utf8);
document.getElementById("decrypted").innerHTML = decrypted;
}
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/aes.js"></script>
<div id="decrypted">Please wait...</div>
<div>
Insert new note:
<input type="text" id="new_note">
<input type="button" id="enc_button" value="Encrypt & Decrypt">
</div>
It looks like decripted IS empty.
you have initialized decripted1
var decrypted1 = CryptoJS.AES.decrypt(encrypted_text,serverkey);
and then tryed to "toString()" the uninitialized decrypted var
decrypted1 = decrypted.toString();
Although I think you don't need this line... (?).
I have some troubles with a simple crypto-challenge.
I want to do following:
getting a url-encoded and base64-encoded value
do url-decoding
do base64-decoding
hash with Sha512
When working with CryptoJS, i use following code:
var parameter = "Akuwnm2318kwioasdjlnmn";
var urlDecoded = decodeURIComponent(parameter);
var base64Decoded = CryptoJS.enc.Base64.parse(urlDecoded);
var hashed = CryptoJS.SHA512(base64Decoded).toString(CryptoJS.enc.Base64);
//hashed = "UxupkI5+dkhUorQ+K3+Tqct1WNUkj3I6N76g82CbNQ0EAH/nWjqi9CW5Qec1vq/qakNIYeXeqiAPOVAVkzf9mA=="/eWTS2lUgCEe6NJDXhNfYvXMRQDvH6k2PHVmy6LJS7RloVvcQcpVjRNVU5lJpAg=="
When working with Closure, i use following code:
var parameter = "Akuwnm2318kwioasdjlnmn";
var urlDecoded = decodeURIComponent(parameter);
var byteArray = goog.crypt.base64.decodeStringToByteArray(urlDecoded);
var base64Decoded = goog.crypt.byteArrayToHex(byteArray);
var sha512 = new goog.crypt.Sha512();
sha512.update(base64Decoded);
var hashed = sha512.digest();
hashed = goog.crypt.byteArrayToHex(hashed);
//hashed = "bc2a878edfffb0937fbc6c0f9dbc9566edc59b74080d68d4c8bdfeb4027f17c4316a02285baaf446872d2df37b1144ac3ce18d62ab9c786b1f1fb18a53acea1d"
So, why are the hashes different?
I would be very happy if someone could tell me how to adapt the Closure-Code, to get the same hash as the CryptoJS code provides.
Thanks a lot!
PS:
I also tried:
var parameter = "Akuwnm2318kwioasdjlnmn";
var urlDecoded = decodeURIComponent(parameter);
var base64DecodedByteArray = goog.crypt.base64.decodeStringToByteArray(urlDecoded);
var sha512 = new goog.crypt.Sha512();
sha512.update(base64DecodedByteArray);
var hashed = sha512.digest();
hashed = goog.crypt.byteArrayToHex(hashed);
//hashed = "531ba9908e7e764854a2b43e2b7f93a9cb7558d5248f723a37bea0f3609b350d04007fe75a3aa2f425b941e735beafea6a434861e5deaa200f3950159337fd98"
but then, as you see, i get another hash. why??
The first hash value is identical to the third, except it is base64-encoded rather than hex-encoded. You can change to hex encoding and get the same value:
var hashed = CryptoJS.SHA512(base64Decoded).toString(CryptoJS.enc.Hex);
//hashed = "531ba9908e7e764854a2b43e2b7f93a9cb7558d5248f723a37bea0f3609b350d04007fe75a3aa2f425b941e735beafea6a434861e5deaa200f3950159337fd98"
The second approach you show has a different value because you are not hashing the same data; you are instead converting the byteArray to a hex string and then hashing that string representation, not the underlying values.