Reputation: 1354
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);
}
Upvotes: 2
Views: 2591
Reputation: 49296
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>
Upvotes: 1