When using Node.js crypto module
const crypto = require('crypto');
HMACseed = crypto.createHmac('sha512', 'a55e3e55ff89d1cfeab1c85ac4dc7517d8d3228bb41a7d86de9cdf5587126de7').update('02de498327ba9544ba3b5c3d855a56a6761737a399d099b46b2a1d69491ca64ae400000001').digest('hex');
console.log(HMACseed)
result
08b87c15c5cc62ebcdb8cf5bf6a61cd168387fcc59db119e19ecd8deb67380dda98dd5faf7409face6ebcb187929176636f593dadbe7d7aa44a1ed59bbe0dff6
But using https://caligatio.github.io/jsSHA/
result
6b1312b3706844b11dd50012dd31be8d77f2f7cd9ec0624f730ee24bc4246084cbcaf10f63610cca1b4cc86e8b32a29b6c495a3b8bd28de4d3fd0b98df483530
key = 'a55e3e55ff89d1cfeab1c85ac4dc7517d8d3228bb41a7d86de9cdf5587126de7'
data = '02de498327ba9544ba3b5c3d855a56a6761737a399d099b46b2a1d69491ca64ae400000001'
I wonder why the jsSHA will result different value of HMAC-256.
You need to using hex as input or it will regard it as text input.
HMACseed = crypto.createHmac('sha512', Buffer.from('a55e3e55ff89d1cfeab1c85ac4dc7517d8d3228bb41a7d86de9cdf5587126de7', 'hex')).update(Buffer.from('02de498327ba9544ba3b5c3d855a56a6761737a399d099b46b2a1d69491ca64ae400000001','hex')).digest('hex');
console.log(HMACseed)
Related
I am working out a custom hybrid encryption system. I've got symmetric encryption & asymmetric encryption & decryption all handled server-side. All I need to work out now is symmetric decryption.
I got some trouble because my client is sending symmetric key, iv & data all in string format (after asymmetric decryption), but CryptoJS is very touchy with it's encoding. It's also very confusing and vague as far as documentation goes- at least for a relatively new developer. I just can't figure out what encoding CryptoJS wants for each argument. I figure I should have guessed right by now, but no.
Docs
Some help I've gotten previously
I'm requesting help getting the encoding right so that I can decrypt with the following. And thanks a lot for any assistance.
Example of data after asymmetric decryption as per below (throw away keys):
symmetricKey: bDKJVr5wFtQZaPrs4ZoMkP2RjtaYpXo5HHKbzrNELs8=,
symmetricNonce: Z8q66bFkbEqQiVbrUrts+A==,
dataToReceive: "hX/BFO7b+6eYV1zt3+hu3o5g61PFB4V3myyU8tI3W7I="
exports.transportSecurityDecryption = async function mmTransportSecurityDecryption(dataToReceive, keys) {
const JSEncrypt = require('node-jsencrypt');
const CryptoJS = require("crypto-js");
// Asymmetrically decrypt symmetric cypher data with server private key
const privateKeyQuery = new Parse.Query("ServerPrivateKey");
const keyQueryResult = await privateKeyQuery.find({useMasterKey: true});
const object = keyQueryResult[0];
const serverPrivateKey = object.get("key");
const crypt = new JSEncrypt();
crypt.setPrivateKey(serverPrivateKey);
let decryptedDataString = crypt.decrypt(keys);
let decryptedData = JSON.parse(decryptedDataString);
// Symmetrically decrypt transit data
let symmetricKey = decryptedData.symmetricKey;
let symmetricNonce = decryptedData.symmetricNonce;
// Works perfectly till here <---
var decrypted = CryptoJS.AES.decrypt(
CryptoJS.enc.Hex.parse(dataToReceive),
CryptoJS.enc.Utf8.parse(symmetricKey),
{iv: CryptoJS.enc.Hex.parse(symmetricNonce)}
);
return decrypted.toString(CryptoJS.enc.Utf8);
}
You are using the wrong encoders for data, key and IV. All three are Base64 encoded (and not hex or Utf8). So apply the Base64 encoder.
The ciphertext must be passed to CryptoJS.AES.decrypt() as a CipherParams object or alternatively Base64 encoded, which is implicitly converted to a CipherParams object.
When both are fixed, the plain text is: "[\"001\",\"001\"]".
var symmetricKey = "bDKJVr5wFtQZaPrs4ZoMkP2RjtaYpXo5HHKbzrNELs8="
var symmetricNonce = "Z8q66bFkbEqQiVbrUrts+A=="
var dataToReceive = "hX/BFO7b+6eYV1zt3+hu3o5g61PFB4V3myyU8tI3W7I="
var decrypted = CryptoJS.AES.decrypt(
dataToReceive, // pass Base64 encoded
//{ciphertext: CryptoJS.enc.Base64.parse(dataToReceive)}, // pass as CipherParams object, works also
CryptoJS.enc.Base64.parse(symmetricKey),
{iv: CryptoJS.enc.Base64.parse(symmetricNonce)}
);
console.log(decrypted.toString(CryptoJS.enc.Utf8));
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
I am looking for standard utility for supporting the encryption & decryption based on the below algorithm in node server side.
algorithm: aes-256-gcm
using the createCipheriv, createDecipheriv from nodejs crypto module.
Please suggest some working references
The utility need to build it from your side, and based on your needs below are the small code may help you to build the utility:
const crypto = require('crypto');
// This two value (ivValueEn , ivValueDe) should be same, to decode the text properly!
// you can generate any strong value and past it at the same place of you can have it from the config value.
const ivValueEn = "c5949f09a7e67318888c5949f09a7e6c09ca51e602867318888c5949f09a7e6c09ca51e602867318888";
const ivValueDe = "c5949f09a7e6c09ca51e602867318888c5949f09a7e6c09ca51e602867319ca51e602867318888";
// insert your key here, better to chose a strong key
const keyValue = "c5949f09a7e6c09a7e6c09ca51e602867318888c5949f09a7e6c09ca51e602867318888";
// slicing are not required you can remove the slice(0,64) part & the console.log as well
const alog = 'aes-256-gcm'
const ivEn = ivValueEn.toString('hex').slice(0,64); console.log(ivEn);
const ivDe = ivValueDe.toString('hex').slice(0,64); console.log(ivDe);
// The one that working with me correctly is to slicing the key to (32) characters.
const key = keyValue.slice(0,32);
const cipher = crypto.createCipheriv(alog,key,ivEn);
const decipher = crypto.createDecipheriv (alog,key,ivDe);
const crypto = require('crypto');
hm = crypto.createHmac("sha256","Some String");
console.log(hm.digest("base64"));
Running this gives me:
Nd6Q8epsIBG+c/jN6TdnfRNbFWCcB7bI0DYkfyDqf+8=
(repl)
But calculating the sha256 at https://approsto.com/sha-generator/ gives me:
fw/WRlO6C7Glec7Str83XpFsxgZiEJ7gwLJPCnUMOmw
Why is there a difference?
Use Hash instead of Hmac.
const crypto = require('crypto');
hash = crypto.createHash("sha256");
hash.update("Some String");
console.log(hash.digest("base64"));
Result:
fw/WRlO6C7Glec7Str83XpFsxgZiEJ7gwLJPCnUMOmw=
See also:
What is the difference between a HMAC and a hash of data?
I have to represent this node.js code in Microsoft Jscript. How can I do that?
const crypto = require('crypto');
var value = 'helloworld';
var hash = crypto.createHash('sha256').update(value).digest('hex')
I'm trying to decode the following base64-encoded ciphertext in Node.js with the built-in crypto library
2tGiKhSjSQEjoDNukf5BpfvwmdjBtA9kS1EaNPupESqheZ1TCr5ckEdWUvd+e51XWLUzdhBFNOBRrUB5jR64Pjf1VKvQ4dhcDk3Fdu4hyUoBSWfY053Rfd3fqpgZVggoKk4wvmNiCuEMEHxV3rGNKeFzOvP/P3O5gOF7HZYa2dgezizXSgnnD6mCp37OJXqHuAngr0pps/i9819O6FyKgu6t2AzwbWZkP2sXvH3OGRU6oj5DFTgiKGv1GbrM8mIrC7rlRdNgiJ9dyHrOAwqO+SVwzhhTWj1K//PoyyzDKUuqqUQ6AvJl7d1o5sHNzeNgJxhywMT9F10+gnliBxIg8gGSmzBqrgwUNZxltT4uEKz67u9eJi59a0HBBi/2+umzwOCHNA4jl1x0mv0MhYiX/A==
It seems to work with PHP's mcrypt functions using the string typeconfig.sys^_- as the key, as shown by inputting the value into http://www.tools4noobs.com/online_tools/decrypt/ and selecting Blowfish, ECB, Base64 decode.
However, when I run the following code in Node.js:
var crypto = require('crypto');
var data = "2tGiKhSjSQEjoDNukf5BpfvwmdjBtA9kS1EaNPupESqheZ1TCr5ckEdWUvd+e51XWLUzdhBFNOBRrUB5jR64Pjf1VKvQ4dhcDk3Fdu4hyUoBSWfY053Rfd3fqpgZVggoKk4wvmNiCuEMEHxV3rGNKeFzOvP/P3O5gOF7HZYa2dgezizXSgnnD6mCp37OJXqHuAngr0pps/i9819O6FyKgu6t2AzwbWZkP2sXvH3OGRU6oj5DFTgiKGv1GbrM8mIrC7rlRdNgiJ9dyHrOAwqO+SVwzhhTWj1K//PoyyzDKUuqqUQ6AvJl7d1o5sHNzeNgJxhywMT9F10+gnliBxIg8gGSmzBqrgwUNZxltT4uEKz67u9eJi59a0HBBi/2+umzwOCHNA4jl1x0mv0MhYiX/A==";
var decipher = crypto.createDecipher('bf-ecb', 'typeconfig.sys^_-');
data = decipher.update(data, "base64", "utf8");
data += decipher.final("utf8");
console.log(data);
I get garbage output:
y
�:����d�(����Q�i��z1��4�� �k�(� ��a5����u��73c/��(ֻ��)��������fȠ���
�ec�-<z�8����(�-L���ԛ�I��1L*��u�4�j-�Чh쭊#\P)?�.�^���q㊬�U���W&�x��85�T-ג9,dE<g}�`*�
��|#����k"�!�D'u���,x��7����
��9q=q�q��ա>�w�T����H3͜�i)R��zy��C��
��o�
I've also tried a test of the library itself, in that it seems to be able to handle stuff it encodes itself fine:
var crypto = require('crypto')
var cipher = crypto.createCipher("bf-ecb", "key");
var data = cipher.update("foobar", "utf8", "base64");
data += cipher.final("base64");
console.log(data);
var decipher = crypto.createDecipher("bf-ecb", "key");
data = decipher.update(data, "base64", "utf8");
data += decipher.final("utf8");
console.log(data);
produces:
y0rq5pYkiU0=
foobar
but copy-and-pasting that base64 string and inputting it into http://www.tools4noobs.com/online_tools/decrypt/ alongside the key "key" produces garbage output also.
Shouldn't these two libraries produce the same output, or is there something I've done wrong?
Node.js computes the MD5 hash of the password before using it as the key. As far as I can tell, mcrypt uses the key as-is.
Compute the MD5 hash of the password, and use that as the mcrypt key.
https://github.com/tugrul/node-mcrypt
var mcrypt = require('mcrypt');
var bfEcb = new mcrypt.MCrypt('blowfish', 'ecb');
bfEcb.open('typeconfig.sys^_-');
var cipherText = new Buffer('2tGiKhSjSQEjoDNukf5BpfvwmdjBtA9kS1EaNPupESqheZ1TCr5ckEdWUvd+e51XWLUzdhBFNOBRrUB5jR64Pjf1VKvQ4dhcDk3Fdu4hyUoBSWfY053Rfd3fqpgZVggoKk4wvmNiCuEMEHxV3rGNKeFzOvP/P3O5gOF7HZYa2dgezizXSgnnD6mCp37OJXqHuAngr0pps/i9819O6FyKgu6t2AzwbWZkP2sXvH3OGRU6oj5DFTgiKGv1GbrM8mIrC7rlRdNgiJ9dyHrOAwqO+SVwzhhTWj1K//PoyyzDKUuqqUQ6AvJl7d1o5sHNzeNgJxhywMT9F10+gnliBxIg8gGSmzBqrgwUNZxltT4uEKz67u9eJi59a0HBBi/2+umzwOCHNA4jl1x0mv0MhYiX/A==', 'base64');
console.log(bfEcb.decrypt(cipherText).toString());
bfEcb.close();