Unlike node.js native crypto library, node-cryptojs-aes removes openssl dependency.
node-cryptojs-aes doesn't make any modification to original cryptojs library, the syntax remains the same in accordance with CryptoJS documentation.
node-cryptojs-aes doesn't rely on any external library, such as native openssl libary or any external node.js modules. As a node.js module, it can simply be installed through npm package management system. There is no configuration needed also.
node-cryptojs-aes works great on frontend data masking and unmasking. Client will do the heavy lifting to decipher and reveal the masked data, reduce server load and processing time.
This is a complete example where server encrypts data, browser requests encrypted data and passphrase, then processes decipher subsequently.
To best demostrate the library structure, and separate client side and server side, the server is going to be hosted on
localhost:3000, whereas client can be run on any
http server. Communication is carried out through JSONP. I real world, however, application can be integrated into Express sinatra pattern.
Browser side is powered by Bootstrap Cover Template.
This part of code snippets are located in examples/server/server.js. Test out in command line:
The logic on node.js server encryption logic consists of two parts.
Right off the bat, it generates random passphrase using the native
node.js crypto library method.
//import crypto module to generate random binary datavar crypto = require'crypto';// generate random passphrase binary datavar r_pass = cryptorandomBytes128;// convert passphrase to base64 formatvar r_pass_base64 = r_passtoString"base64";console.log"passphrase base64 format: ";console.logr_pass_base64;
Then, it performs data encryption
// import node-cryptojs-aes modules to encrypt or decrypt datavar node_cryptojs = require'node-cryptojs-aes';// node-cryptojs-aes main object;var CryptoJS = node_cryptojsCryptoJS;// custom json serialization formatvar JsonFormatter = node_cryptojsJsonFormatter;// message to ciphervar message = "I love maccas!";// encrypt plain text with passphrase and custom json serialization format, return CipherParams object// r_pass_base64 is the passphrase generated from first stage// message is the original plain textvar encrypted = CryptoJSAESencryptmessage r_pass_base64 format: JsonFormatter ;// convert CipherParams object to json string for transmissionvar encrypted_json_str = encryptedtoString;console.log"serialized CipherParams object: ";console.logencrypted_json_str;
JsonFormatter is a custom json serialization implementation, you might create your prefered json serialization to fit into your own structure. According to CryptoJS documentation, the code snippets of JsonFormatter shipped with node-cryptojs-aes is as follows.
//create custom json serialization formatvar JsonFormatter =// create json object with ciphertextvar jsonObj =ct: cipherParamsciphertexttoStringCryptoJSencBase64;// optionally add iv and saltif cipherParamsivjsonObjiv = cipherParamsivtoString;if cipherParamssaltjsonObjs = cipherParamssalttoString;// stringify json objectreturn JSONstringifyjsonObj// parse json stringvar jsonObj = JSONparsejsonStr;// extract ciphertext from json object, and create cipher params objectvar cipherParams = CryptoJSlibCipherParamscreateciphertext: CryptoJSencBase64parsejsonObjct;// optionally extract iv and saltif jsonObjivcipherParamsiv = CryptoJSencHexparsejsonObjiv;if jsonObjscipherParamssalt = CryptoJSencHexparsejsonObjs;return cipherParams;;
The serialized cipherParams object defaults OPENSSL-compatible format. It contains 3 properties, a IV, a salt and a cipher text encrypted by AES.
"ct":"gpiVs3D4dqUI/G8F+8Elgg==" //result of encryption performed on plaintext"iv":"008fffd119971f34dbd29e80a823cef2" //IV"s":"43e2badf9eb689fd" //salt
If running express to serve http request on node.js, the response can be
// encryption logic here//express 3 applicationvar express = require'express';var app = express;// browser request serialized cipherParams object in path /crypto/encrypted, with JSONP supportappget'/crypto/encrypted'//JSONP allow cross domain AJAXresponsejsonpencrypted : encrypted_json_str;;// browser request passphrase in path /crypto/passphrase, with JSONP supportappget'/crypto/passphrase'//JSONP allow cross domain AJAXresponsejsonppassphrase : r_pass_base64;;applisten3000;
This part of code snippets are located in examples/browser.
On browser side, The encrypted JSON string(masked data) should be embedded in a hidden tag when first time construct the page.
For demostration and simplicity, in our example, the encrypted JSON string is added to a hidden tag through AJAX.
// retrieve encrypted json string when loading page// define server cipherParams JSONP pathvar encrypted_url = "?";// JSONP AJAX call to node.js server running on localhost:3000$getJSONencrypted_url// retrieve encrypted json stringvar encrypted_json_str = dataencrypted;console.log"encrypted json string: ";console.logencrypted_json_str;// store masked data into a div tag$"#data_store"textencrypted_json_str;;
The main reason for applying masking to a data field is to protect data that is classified as personal identifiable data, personal sensitive data or commercially sensitive data.
Hacker and expert won't be able to access real messages through frontend code inspecting approach, such as
Chrome developer tools.
Data masking applied here protects sensitive data(such as credit card number) from being viewed by frontend code analysis without authorization.
It is worth noting that this approach comes into handy if there are requirements large amount of sensitive data need to be processed and stored in the client side at page construction time. Once passphrase is passed from server, client will do the heavy lifting to decipher and reveal the masked data, reduce server load and processing time.
On the other hand, AJAX request will consume bandwidth when passing large amount sensitive data in real time, impose heavy workload on server at
spike time, also browsing is delayed if network is lagging.
Last but not least,
node-cryptojs-aes frontend data masking is aimed at preventing frontend data hacker malicious behaviour, it can't stop MITM attack.
The logic of browser decryption also can be divided into two parts.
Retrieve passphrase with a AJAX call
// define server passphrase JSONP pathvar passphrase_url = "?";// JSONP AJAX call to node.js server running on localhost:3000$getJSONpassphrase_url// retrieve passphrase stringvar r_pass_base64 = datapassphrase;console.log"passphrase: ";console.logr_pass_base64;// decipher part;
Last step, data is unmasked by calling browser AES script, take passphrase and JsonFormatter as parameter
// take out masked data from div tagvar encrypted_json_str = $"#data_store"text;// decrypt data with encrypted json string, passphrase string and custom JsonFormattervar decrypted = CryptoJSAESdecryptencrypted_json_str r_pass_base64 format: JsonFormatter ;// convert to Utf8 format unmasked datavar decrypted_str = CryptoJSencUtf8stringifydecrypted;console.log"decrypted string: " + decrypted_str;// convert into unmasked data and store in the div tag$"#data_store"textdecrypted_str;
Last thing, don't forget to add browser AES script and JsonFormatter to your index.html file. You can load it straight away via github CDN network
Or you can find your own copy at client/ folder
Install through npm
npm install node-cryptojs-aes
node-cryptojs-aes Version 0.3.8 - 23/02/2014
node-cryptojs-aes Version 0.3.7 - 01/08/2012
node-cryptojs-aes Version 0.3.4 - 21/07/2012
To support the developer's development and contribute to open source community and node.js community, you might donate money to help out your fellowmen, no matter how large or small, it all counts. With your effort, we can make a better world, Thank you.