Modern applications needs to consider informatic security as important key through development and infraestructure implemented in the project. So, I consider a good practice are implement basic and strong encryption methods in every project to protect and hardening our platform and even more when we want to deploy a public API or corporative services.
This article is focused on AES (Advanced Encryption Standard) a commonly and easy to use algorithm. A good introduction https://youtu.be/NHuibtoL_qk.
Backend
To cipher data with Node.js you could use “crypto-js“, a library that contains multiple modules to encrypt data and is the most used in the js-world. You can see it in action in the following code.
| /// Dependencies | |
| const _config = require('config'); // Current version ^1.20.4 | |
| const _crypto = require("crypto-js"); // Current version ^3.1.9-1 | |
| /// Properties | |
| var _password = _config.aesPassword; // Good recomendation, | |
| // don't save passwords | |
| // in plain text or source code | |
| var _textToEncrypt = 'Hello World!'; | |
| const encrypt = function (text) { | |
| return (_crypto.AES.encrypt(text, _password)).toString(); | |
| } | |
| const decrypt = function (ciphertext) { | |
| var bytes = _crypto.AES.decrypt(ciphertext, _password); | |
| return bytes.toString(_crypto.enc.Utf8); | |
| } | |
| var _cipherText = encrypt(_textToEncrypt); | |
| var _uncipherText = decrypt(_cipherText); | |
| console.log(`Encrypted message: ${_cipherText}`); | |
| console.log(`Decrypted message: ${_uncipherText}`); | |
| /* | |
| * Using czfP2jvyUn7wwrZU8k7U as password: | |
| * $ Encrypted message: U2FsdGVkX19jEOgGQ0GA9VHYVg53lp4JQXLkBKf7ZT4= | |
| * $ Decrypted message: Hello World! | |
| */ |
Frontend
Now, if you want to encrypt data in frontend exist an interesting library called “aes-js“, the difference is you can use public CDN and you can choose length of keys encryption by default. In the following example you can see Output Feedback as operation method (a video to explain what is it https://youtu.be/ASR8TDIf_6c).
| /// Use public CDN in your frontend <script type="text/javascript" src="https://cdn.rawgit.com/ricmoo/aes-js/e27b99df/index.js"></script> | |
| // Convert it to base 36 (numbers + letters), and grab the first 9 characters | |
| // after the decimal. | |
| var randomStringGenerator = function (length, prefix) { | |
| return (prefix == undefined ? 'key-' : prefix) + Math.random().toString(36).substr(2, (length == undefined ? 5 : length)); | |
| } | |
| // Get ASCII numbers from a string as array | |
| var stringToAscii = function(input){ | |
| var result = []; | |
| for (var key in input) { | |
| if (input.hasOwnProperty(key)) { | |
| result.push(input[key].charCodeAt()); | |
| } | |
| } | |
| return result; | |
| } | |
| var keyGenerator = function(){ | |
| return stringToAscii(randomStringGenerator(12)).join(':'); | |
| } | |
| var ivGenerator = function(){ | |
| return stringToAscii(randomStringGenerator(10, 'keyiv-')).join(':'); | |
| } | |
| var encrypt = function (cipherText){ | |
| var textBytes = aesjs.utils.utf8.toBytes(cipherText); | |
| var aesOfb = new aesjs.ModeOfOperation.ofb(key, iv); | |
| var encryptedBytes = aesOfb.encrypt(textBytes); | |
| return aesjs.utils.hex.fromBytes(encryptedBytes); | |
| } | |
| var decrypt = function(mesage){ | |
| var encryptedBytes = aesjs.utils.hex.toBytes(message); | |
| var aesOfb = new aesjs.ModeOfOperation.ofb(key, iv); | |
| var decryptedBytes = aesOfb.decrypt(encryptedBytes); | |
| return aesjs.utils.utf8.fromBytes(decryptedBytes); | |
| } | |
| var key = ''; | |
| var iv = ''; | |
| $(document).ready(function () { | |
| key = keyGenerator(); | |
| iv = ivGenerator(); | |
| console.log(`Your Key: ${key}`); | |
| console.log(`Your IV: ${iv}`); | |
| do { | |
| key = prompt('Insert your key:'); | |
| } while (key == null); | |
| do { | |
| iv = prompt('Insert your IV:'); | |
| } while (iv == null); | |
| // Get an array from given strings | |
| key = key.split(':').map(function (value) { return parseInt(value) }); | |
| iv = iv.split(':').map(function (value) { return parseInt(value) }); | |
| }); |
The last example could be used in a private chat to prevent MITM (Man-in-the-middle) attack. A pretty project and easy to edit https://github.com/IgorAntun/node-chat.
Finally, if you want to know more about encryption systems, algorithms and more you could subscribe in the Udacity Course https://www.udacity.com/course/applied-cryptography–cs387
