Java and javascript generates different output for Base64 Hmac SHA256 - javascript

When I tried to create similar function in Java and javascript which outputs a Base64 string of a Hmac SHA 256 encryption, the output given is not the same.
Javascript
var dataToSign = "message";
var secret = "secret";
function generateAuthHeader(dataToSign){
var hash = CryptoJS.HmacSHA256(dataToSign,secret);
return hash.toString(CryptoJS.enc.Base64);
which outputs
+eZuF5tnR65UEI+C+K3os8Jddv0wr95sOVgixTAZYWk=
Java
String key="secret";
String dataToSign = "message";
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
sha256_HMAC.init(secret_key);
System.out.println(Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(dataToSign.getBytes("UTF-8"))));
which outputs
i19IcCmVwVmMVz2x4hhmqbgl1KeU0WnXBgoDYFeWNgs=
is there errors in my code?

What's the value of hash in the JavaScript version and what's the value of sha256_HMAC.doFinal(dataToSign.getBytes("UTF-8")) in the Java version?
Also, can you please try getting the Base64 repr in JavaScript:
CryptoJS.enc.Base64.stringify(hash);
instead of hash.toString ?
Also UTF-8 shouldn't make a difference in the Java version, but I'd try to remove those and simply do getBytes() everywhere.

Related

How to decript password using nodejs or javascript

Tried to see my password from my database.My password is test123 So in my database i have saved like this : $2a$10$0V1JkVfl8n.WD/QbInIWqubjcaxnCCnP3K.bhuxjAQbJ9LyFiNTdu. How to see my password again like test123 from $2a$10$0V1JkVfl8n.WD/QbInIWqubjcaxnCCnP3K.bhuxjAQbJ9LyFiNTdu.
Can we do using nodejs or javascript?
var crypto = require("crypto");
var password = '$2a$10$0V1JkVfl8n.WD/QbInIWqubjcaxnCCnP3K.bhuxjAQbJ9LyFiNTdu';
var algorithm = "aes-192-cbc"; //algorithm to use
const key = crypto.scryptSync(password, 'salt', 24); //create key
var text = '?????????????????????????"; //text to be encrypted
const iv = Buffer.alloc(16, 0);
const cipher = crypto.createCipheriv(algorithm, key, iv);
var encrypted = cipher.update(text, 'utf8', 'hex') + cipher.final('hex'); // encrypted text
const decipher = crypto.createDecipheriv(algorithm, key, iv);
var decrypted = decipher.update(encrypted, 'hex', 'utf8') + decipher.final('utf8');
console.log(decrypted); //Output should be like test123
I don't believe it's meant to be decrypted on purpose.
"Cryptographic hash functions are a special type of one-way calculation"
What is hashing?
Cryptographic hash functions are a special type of one-way
calculation. They take a string of data of any size and always give an
output of a predetermined length. This output is called the hash, hash
value or message digest. Since these functions don’t use keys, the
result for a given input is always the same.
Encryption, hashing, salting – what’s the difference?
StackOverflow question:
"HMAC is a MAC/keyed hash, not a cipher. It's not designed to be
decrypted. If you want to encrypt something, use a cipher, like AES,
preferably in an authenticated mode like AES-GCM.
The only way to "decrypt" is guessing the whole input and then
comparing the output."
How can I decrypt a HMAC?
All these encrypting algorithms are trying NOT to do exactly what you are asking for :). It's a one way process. That means there is no well-known library in javascript or nodejs world to easily decrypt your password. Maybe there might be some applications, just using try-and-error method to guess your password.
It's not possible. Your password had the following functions applied.
Saved value = HASH(Password + salt)
That can't be undone.

Base64 encoding of String in Node.js

I try to encode a string in both browser and server but I have different base64 encoding for a specific string
Here is my string: "£aº©S=³hPó c¨¸" (Hexa: 00a3006100ba00a900940053003d00b30068005000f300900020006300a800b8 )
Client-side: I encode this String using btoa() and I have : o2G6qZRTPbNoUPOQIGOouA== and this is the result I expect.
Server-side: I code this String using Buffer according to this answer in Node.js i have :
var ciphertext = ... // myString
console.log(ciphertext.hexEncode()); // 00a3006100ba00a900940053003d00b30068005000f300900020006300a800b8
console.log(Buffer.from(ciphertext, 'utf8').toString('base64')) // wqNhwrrCqcKUUz3Cs2hQw7PCkCBjwqjCuA==
console.log(Buffer.from(ciphertext, 'ucs2').toString('base64')) // owBhALoAqQCUAFMAPQCzAGgAUADzAJAAIABjAKgAuAA=
I managed to obtain the base64 encoding I expect using the node-package base-64
I still don't know why, so if someone has a clue
var base64 = require('base-64');
var ciphertext = ...; //myString
var encoded = base64.encode(bytes);
console.log(encoded); // o2G6qZRTPbNoUPOQIGOouA==

CryptoJS not decrypting non-Latin characters faithfully

I am trying to use CryptoJS AES, like so:
var msg = "café";
var key = "something";
var c = CryptoJS.AES.encrypt(msg, key).toString();
CryptoJS.AES.decrypt(c, key).toString(CryptoJS.enc.Latin1);
Unfortunately this returns café, not café. Clearly Latin1 is not the right encoding to use, but I can't find a better one. Is there a solution?
Thanks.
You are just missing the format
The proper way is using CryptoJS.enc.Utf8
So, Please try:
CryptoJS.AES.decrypt(c, key).toString(CryptoJS.enc.Utf8);
https://code.google.com/p/crypto-js/#The_Hasher_Input
The hash algorithms accept either strings or instances of CryptoJS.lib.WordArray [...] an array of 32-bit words. When you pass a string, it's automatically converted to a WordArray encoded as UTF-8.
So, when you pass a string (and don't use CryptoJS.enc.* to generate a WordArray) it automatically converts the string (message) to a utf8 WordArray.
See here for sample roundtrip encrypt/decrypt:
https://code.google.com/p/crypto-js/#The_Cipher_Output
Here's a jsfiddle to play with CryptoJS
https://jsfiddle.net/8qbf4746/4/
var message = "café";
var key = "something";
var encrypted = CryptoJS.AES.encrypt(message, key);
//equivalent to CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(message), key);
var decrypted = CryptoJS.AES.decrypt(encrypted, key);
$('#1').text("Encrypted: "+encrypted);
$('#2').text("Decrypted: "+decrypted.toString(CryptoJS.enc.Utf8));
To emphasize my point here is the same thing using Latin1 encoding:
https://jsfiddle.net/3a8tf48f/2/
var message = "café";
var key = "something";
var encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Latin1.parse(message), key);
var decrypted = CryptoJS.AES.decrypt(encrypted, key);
$('#1').text("Encrypted: " + encrypted);
$('#2').text("Decrypted: " + decrypted.toString(CryptoJS.enc.Latin1));
On a side note, the API would probably be better if it only accepted WordArray and didn't overload the toString method (which is just a convenience interface to CryptoJS.enc.*.stringify). The string conversion magic is a little misleading.
You are trying to decrypt your data as a Latin1 string, even though your input string is not in Latin1. The encoding used by CryptoJS internally is not the same as the encoding you use to write the input file.
You need to specify the same encoding both when encrypting (for the string -> byte array conversion) and when decrypting (for the byte array -> string conversion).

MD5.ComputeHash(Encoding.Unicode.GetBytes(value)) into javascript

I need to translate the line below from vb.net to javascript
MD5.ComputeHash(Encoding.Unicode.GetBytes(value))
Im trying to use CryptoJS but I get diffrent results as I need to pass a string into that but a byte array into the MD5 function in VB.net
Can anyone help?
Thank you
Encoding.Unicode is a (misleading) name used by Windows for the UTF-16LE encoding.
However the CryptoJS functions, when given a string, encode it to bytes using the (more common) UTF-8, not UTF-16LE:
The hash algorithms accept either strings or instances of CryptoJS.lib.WordArray. A WordArray object represents an array of 32-bit words. When you pass a string, it's automatically converted to a WordArray encoded as UTF-8.
So you will need to create a WordArray from the string yourself before passing it in to MD5. With a new enough CryptoJS there's a function to do that for you:
CryptoJS.MD5(CryptoJS.enc.Utf16LE.parse(str))
IN C#:
var data = md5.ComputeHash(Encoding.Default.GetBytes(password));
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++) {
stringBuilder.Append(data[i].ToString("x2"));
}
return stringBuilder.ToString();
In Node.js
const crypto = require('crypto');
crypto.createHash('md5').update(value).digest('hex');

What is DigestUtils sha256 encoding equivalent from JavaScript?

I call following and create the password hash.
ByteString password = ByteString.copyFrom(DigestUtils.sha256("mypassword"));
But now I need to send the sha256 converted password message from client (JavaScript). I tired to use CryptoJS as following
var pass = CryptoJS.SHA256(document.getElementById('password').value);
var passhash = pass.toString(CryptoJS.enc.Latin1)
login(passhash);
I tried all Base64, Latin1, and Hex types to get the string. But it will not produce the same password as the one in Java
Problem was with character encoding. Following fixed the problem.
in JS:
var password = pass.toString(CryptoJS.enc.Utf16);
In Java:
byte[] passhash = jsCryptoString.getBytes("UTF-16BE");

Categories

Resources