JavaScript Encryption
Posted by JanWan
Last Updated: July 18, 2012

JavaScript Encryption

There are a number of things that are thought to be impossible to do with JavaScript. Some of them are impossible while others are merely very difficult or require too much code to make them practical. One task that most experienced JavaScript programmers consider to be impossible is to be able to password protects a web page using nothing but JavaScript. Most consider that there is no way to hide the password such that the code cannot be reverse engineered or bypassed within a few minutes.

This would be true if it were not possible to encrypt the web page content using a secure two way encryption algorithm. The reason most discard this possibility is that they don't know of any such encryption code written in JavaScript that is small enough in size to be usable in a web page.

Back in 2001 Fritz Schneider wrote a JavaScript version of the Rijndael encryption algorithm in JavaScript. His version is about 20k in size making it somewhat large to use in web pages on a regular basis but small enough to be somewhat usable. He kindly gave permission to allow anyone to use his script provided that they leave his copyright notice intact. Unfortunately his web site referred to in the script seems to have vanished and so if it were not for the other sites that had already obtained copies of his script this valuable work would have been lost.

By removing all of the comments and whitespace and changing the names of the variable and internal functions I have managed to produce a version of his script that is only 6.6k in size (1/3 the size of his original) which is just about small enough to make it practical to attach to a web page. His script also has a byteArrayToString() function but no stringToByteArray() function and so I have also added the latter function to the code. I have also added a random key generator to the code for generating random numbers that can be used as passwords.

With this encryption method, practical password protection of web pages becomes possible by simply including the encrypted version of the page content and requiring that plus the correct password to be entered in order to restore the original readable content and display the page. It still suffers from the common client side problem of not being able to display anything for people who have JavaScript disabled (only a server side password protection can resolve that). It does provide the most secure means for people without server side access to password protect their page content such that it would be just about impossible for anyone to work out the correct password to use to view the page short of a brute force approach of continuing to try password after password until such time as the correct password is identified.

There are two steps involved with using this encryption algorithm. The first step is to use it to encrypt content and the second step is to use it with that encrypted content in order to allow the original content to be restored. With my extra function added, there are two ways that we can save the encrypted content. We can save it either as a series of hexadecimal values (where the encrypted content will be double the length of the original) or we can store it as a string which will be about the same length as the original but which will contain characters that will be considered to be invalid in certain situations.

Let's begin by looking at how you would write the code to convert a simple text string into its encrypted equivalent.

var plaintext = "Happy Birthday!";
var key = hexToByteArray(genkey());
var mode = 'ECB'; // ECB or CBC
var ciphertext = 
  byteArrayToHex(rijndaelEncrypt(plaintext,key, mode));

This code will convert the text "Happy Birthday!" into an encrypted string using a randomly generated password. We will need to capture the value in the key variable in order to feed that into the code that will convert the encrypted version back into the original. This version creates a hexadecimal string as its output. To obtain an ASCII string instead we simply substitute the byteArrayToString() function for byteArrayToHex() in the last line.

To be able to convert the encrypted string back into readable text we need to reverse the process. To do this we need to input both the encrypted text and that key value into the following code.

var decryptedtext = byteArrayToString(
  rijndaelDecrypt(hexToByteArray(ciphertext), key, mode));

Again, if the encrypted value is an ASCII string instead of hexadecimal we substitute stringToByteArray() for hexToByteArray() in the code.

Of course you also need the encryption functions themselves. My compressed copy of these functions can be copied from the below text area and incorporated into your JavaScript code in whatever way you find appropriate (as long as the comments at the top are left intact). Simply press the "Highlight All" button and then copy and paste the script.

J.W. PRODUCTION

Related Content