Professional Documents
Culture Documents
CryptoJS Tutorial For Dummies PDF
CryptoJS Tutorial For Dummies PDF
CryptoJS Tutorial For Dummies PDF
davidebarranca.com/2012/10/crypto-js-tutorial-cryptography-for-dummies/
[Updated October 16 th 2012 with corrected information from CryptoJS author Jeff Mott –
look for the UPDATED tag below]
The Google Code Crypto-JS page titles “JavaScript implementations of standard and
secure cryptographic algorithms“ and that’s exactly what it’s all about. I strongly suggest
you to read the QuickStart Guide: this CryptoJS Tutorial for Dummies is just made with
comments in the margin of it – underlining important stuff I didn’t notice when I first
approached it. The official documentation is precise yet kind of succint – it makes sense
to those who master the topic, but it may disorient the newcomers (like me when I get there for the first time).
I’m just on my way learning both cryptography theory and this nice JS library, the following is only a collection of
basic advices and personal notes. Please forgive me for using a very… non-specialized jargon.
Caveat: I use to write code in Extendscript – which is an Adobe made superset of Javascript adding
nice extras, such as: file-system access, user interface development tools, external communication,
preprocessing directives, XML integration, etc. I say so because it seems that my mindset is a bit
shifted from the one of the pure Javascript developer (for instance, I’ve not to worry about privacy
issues arising from readable code – my .jsx files are binary encrypted by default when I export them
from the ESTK – ExtendScript ToolKit). I use to write Coffeescript, a nice smart language that
compiles to Javascript, but I won’t us it here.
Files
First, download the CryptoJS package (3.0.2 at the time of this post). It contains two folders:
Components files have dependencies: you have to link at least core.js, while rollups are quite self contained. In
Extendscript, save a test.jsx file alongside (or within) the CryptoJS folder and set the preprocessing directives:
1 #include "components/core-min.js"
2 #include "rollups/sha1.js"
3 #include "rollups/aes.js"
4 #include "components/enc-base64-min.js"
5 #include "components/enc-utf16-min.js"
The #include (redundant here) are the equivalent of the following tag in HTML documents:
1 <script src="http://crypto-js.googlecode.com/svn/tags/3.0.2/build/rollups/aes.js"></script>
Be aware that you need to save the file at least once otherwise the include can’t resolve the path.
Mind you, quoting the Guide: “When you use a WordArray object in a string context “, that is, an alert box or the
Console, “it’s automatically converted to a hex string“.
CryptoJS can manage different encodings, such as Base64, Hex, Latin1, UTF-8 and UTF-16. If you wonder how
data would look like converted to them, paste this script in ESTK (Adobe’s ExtendScriptToolKit):
1 #include "components/enc-base64-min.js"
2 #include "components/enc-utf16-min.js"
3
4 // Save at least once in the appropriate folder in order to
5 // help the #include to resolve the path
6
7 var wordArray = CryptoJS.lib.WordArray.random(32);
8 alert("Random WordArray" +"\nHex: "+ wordArray + "\n\nBase 64: " +
CryptoJS.enc.Base64.stringify(wordArray) +"\n\nLatin 1: " + CryptoJS.enc.Latin1.stringify(wordArray) +
"\n\nUTF-8: " + CryptoJS.enc.Utf8.stringify(wordArray) + "\n\nUTF-16: " +
CryptoJS.enc.Utf16.stringify(wordArray))
The output is as follows – I’ve used an Alert box because ESTK’s $.writeln() (as I suspect both console.log() and
debug(), depending on the tool you use to run your JS code) can’t output but Hex and Base64:
2/7
Conversion Functions
1 CryptoJS.enc./Encoding/.parse();
2 // interprets the param as /Encoded/ // and converts it to Word Array
3
4 CryptoJS.enc./Encoding/.stringify();
5 // interprets the param as Word Array // and converts it to the /Encoded/ String
6
7 var wordArray = CryptoJS.enc.Utf16.parse('Hello, World!'); // Word Array
8 var utf16 = CryptoJS.enc.Utf16.stringify(wordArray); // String
3/7
1 // Encodings:
2 var words = CryptoJS.enc.Base64.parse('SGVsbG8sIFdvcmxkIQ==');
3 var base64 = CryptoJS.enc.Base64.stringify(words);
4
5 var words = CryptoJS.enc.Latin1.parse('Hello, World!');
6 var latin1 = CryptoJS.enc.Latin1.stringify(words);
7
8 var words = CryptoJS.enc.Hex.parse('48656c6c6f2c20576f726c6421');
9 var hex = CryptoJS.enc.Hex.stringify(words);
10
11 var words = CryptoJS.enc.Utf8.parse('♦')
12 var utf8 = CryptoJS.enc.Utf8.stringify(words);
13
14 var words = CryptoJS.enc.Utf16.parse('Hello, World!');
15 var utf16 = CryptoJS.enc.Utf16.stringify(words);
Hash Functions
So to speak, hashers are functions that take an input (no matter how large) and maps it to a fixed size, smaller one
(the hash, or checksum). You can’t convert a hash back to the original input, yet you can check if the original data
has been corrupted comparing the hashes.
CryptoJS implements MD5, SHA-1 (used by Git) and its variant (2, 224, 384, 256 and 512).
The input "Message" can either be a WordArray or a String (which will automatically be converted to the former,
encoded UTF-8). Then you may:
Ciphers
CryptoJS implements several Cipher Algorithms – in the following example AES:
4/7
1 #include "rollups/aes.js"
2
3 var encrypted = CryptoJS.AES.encrypt("Message", "Secret Passphrase");
4 $.writeln(encrypted);
5 // AABsAABkAABiAAAAAAAAAABNAABlAABPAAC0AABHAAA=
6
7 var decrypted = CryptoJS.AES.decrypt(encrypted, "Secret Passphrase");
8 $.writeln(decrypted);
9 // 4d657373616765
The encryption results in a Base64 string, while the decrypted string is Hex. To get back the “Message” you need to:
1 $.writeln(decrypted.toString(CryptoJS.enc.Utf8));
2 // Message
If you run the encryption code several times, you’ll notice that the result will change:
yet each one of them will always decrypt to “Message”. How come?
I’m not a cryptography expert – my raw understanding of the matter (after digging Wikipedia and StackOverflow) is
as follows.
Human memorizable passphrase are known to be bad ones. In order to make them more secure you can add a
bunch of random bits (the salt) so that the actual key = function(Salt, Passphrase). An effect of Salt is
that the same passphrase doesn’t always produce the same key.
IV (initialization vector) is used, similarly, to ensure that the same plaintext (“Message”) doesn’t return the same
ciphertext. It appears that Salt is used with passphrase to generate a key for encryption, then the resulting
encryption is processed with IV. So to speak, the encryption = function(plaintext, passphrase,
salt, IV). So when you write:
5/7
1 var encrypted = CryptoJS.AES.encrypt("Message", "Secret Passphrase");
CryptoJS randomly generates for you what it need. [ UPDATED] Alternatively, you can specify:
The encrypt function takes a plaintext input as a String or WordArray (the “Message”), and either a similar
passphrase or Hex Key and IV.
[UPDATED] It’s important to reaffirm that, if you use a String as a passphrase, CryptoJS uses it to generate a
random key and IV:
When it comes to the output, things are a bit different because if you:
Actually, the encryption output is an object called CipherParams, and you can access its properties:
I’ve had some troubles understanding why they use this object as the vector of encrypted data – the pack of bits you
and the other guy oversea securely swap. It looks like you’re putting your treasure map into a casket and ship it with
the keys to open it (I would have used the ciphertext only). It puzzled me because you can successfully write:
6/7
1 var encrypted = CryptoJS.AES.encrypt("Message", "Secret Passphrase");
2 var decrypted = CryptoJS.AES.decrypt(encrypted, encrypted.key, { iv: encrypted.iv});
[UPDATED] The explanation came directly from CryptoJS author Jeff Moss who wrote me:
Although the key is a property in the CipherParams object, the key is not included when that
CipherParams object is serialized to a string. By default, CipherParams objects are serialized using a
format from OpenSSL. Just do encrypted.toString(), and you can safely send that to the other side of
the ocean.
So the alert(encrypted); hex string you see in the last but one code block is definitely safe to use and share:
There’s definitely more to dig in this great CryptoJS library, I’m looking forward to explore it! This should be just
enough to let you start implementing cryptography in your own projects.
7/7