RSAJAX

By Andrew Peace

Introduction

RSAJAX is a simple JavaScript and PHP library for secure encrypted AJAX calls. It offers a comfortable level of security without the need for an SSL certificate or HTTPS encrypted connection. Using the library is easy, it looks like this:

In the JavaScript:

//in the onLoad event
document.onload = rsajax.initiate_session
//later, when an action is performed, first get a form value
var emailAddr = document.getElementById('emailAddr').value;

//encrypt it
emailAddr = rsajax.encrypt(emailAddr);

//perform an AJAX call that sends the value to the server
...
//pretend this function recieves the AJAX return value
function parse_ajax_return_value(returnValue)
{
    //decrypt the value
    returnValue = rsajax.decrypt(returnValue);
    
    //do whatever you want with the value
    ...
}

In the PHP:

//get the encrypted value
$value = $_GET['email_addr'];

//decrypt it
$value = rsajax_decrypt($value);

//do something with it
...
$return_value = "Success!";

//encrypt the return value
$return_value = rsajax_encrypt($return_value);

//send back the return value however you want
print $return_value;

Licensing

RSAJAX is MIT licensed. The license may be read at http://www.andrewpeace.com/rsajax/LICENSE. A file named LICENSE is included with the RSAJAX source files, and it contains the same information.

For a list of external libraries used, their owners, and their owners' web sites, see the files section.

Philosophy and Intended Usage

RSAJAX is inteded for use by web sites that have a low budget and a need for simple, good-enough encryption. It allows an application to encrypt transactions between the client and the server with a level of security suitable for non-essential, non-sensitive, non-personal data.

I would use RSAJAX when sending email addresses, street addresses, phone numbers, and passwords via AJAX, unless the password is being used to safeguard sensitive data.

I would not use RSAJAX when sending social-security numbers, credit-card numbers or finanical data via AJAX. These types of data warrant the use of an SSL certificate and HTTPS connection.

See also: Usage Notes for Developers.

Demos

Files

Download all source files, compressed:

Here is a list of each file in RSAJAX, its download URL, and who it was created by:

Filename URL Creator
rsajax.js http://www.andrewpeace.com/rsajax/rsajax.js Andrew Peace
rsajax.php http://www.andrewpeace.com/rsajax/rsajax.php.txt Andrew Peace
get_key.php http://www.andrewpeace.com/rsajax/get_key.php.txt Andrew Peace
set_key.php http://www.andrewpeace.com/rsajax/set_key.php.txt Andrew Peace
jquery-1.3.2.min.js http://code.google.com/p/jqueryjs/downloads/detail?name=jquery-1.3.2.min.js John Resig
rc4.js http://farhadi.ir/works/rc4 Ali Farhadi
rc4.php http://farhadi.ir/works/rc4 Ali Farhadi
rsa.class.php http://www.phpclasses.org/browse/file/20511.html* Khaled Al-Shamaa
rsa.js http://www.andrewpeace.com/rsajax/rsa.js** David Shapiro

*Unfortunately, you must create a free account in order to view and download this file.

**rsa.js is a compilation of three JavaScript files written by David Shapiro: BigInt.js, Barrett.js, and RSA.js.

Goals for the Library

As it stands now, RSAJAX is barely a library at all. However, my goal is for RSAJAX to someday be a robust, compact library for encrypting and decrypting AJAX transactions on the client and server sides. The following is a list of my most immediate goals for the library.

And eventually, once I have my design patterns down, I would like to try and support the following server-side environments (and more, hopefully):

Change Log

Version Date Changes
0.0.2
(tar.gz | zip)
2009-05-19
  • Realized that generating a new RSA key each session is a bad idea. RSA keys are now hard-coded in rsajax.php
0.0.1
(tar.gz | zip)
2009-05-18
  • rsajax.js - moved everything inside a containing object
  • rsajax.js - re-wrote random_key for more effeciency and flexibility
  • rsajax.js - removed some leftover debugging code!
0.0.0
(tar.gz | zip)
2009-05-29
  • First pass

How RSAJAX Works

The server stores a private and public RSA key, the latter of which is shared with the client-side via a regular AJAX call. The JavaScript then generates an RC4 encryption key, which is a simple matter of generating a random 256-character-long string. JavaScript then encrypts its RC4 key with the server's public RSA key, and sends it to the server, where it is decrypted with the private RSA key and stored.

From that point on, making a secure AJAX call is simple. First, JavaScript encrypts any values being sent to the server using the public RSA key. Once the server receives an encrypted value, it decrypts it with its private key. This is exactly the same thing that happened when the client's RC4 key was shared with the server.

When the server is ready to respond, it encrypts its response via RC4 using the client's key, which it has stored. Upon receiving the AJAX response, the JavaScript can then decrypt that value using its RC4 key.

Shazam! Encrypted on the way up, encrypted on the way down.

RSA and RC4?

It may seem silly to use RSA for encryption on the way up and RC4 for encryption on the way down. After all, this means that four libraries are needed just for encryption and decryption--RSA and RC4 on both the client and server side.

However, it is this way for a reason.

To begin with, the encryption method used on the server side must be public-key. If the server used private-key encryption, there would be no way for it to securely pass a key to the client. So, RSA is used to send data to the server.

There are two problems with using RSA to send data to the client.

For one, RSA decryption is typically a lot slower than RSA encryption. Since RSA encryption in JavaScript already requires some pretty funky libraries for dealing with large numbers, it's best to leave RSA decryption on the server-side where it can be handled.

For two, JavaScript has no good way of storing or generating public and private RSA keys. In order to generate RSA keys, two big prime numbers are needed. On the server side, getting prime numbers is easy. Just access a file, a database, or an external API that will provide them for you. But since JavaScript can't do any of these things without making a (most-likely insecure) call to some server, it's futile to even attempt RSA key generation on the client side. RC4 uses a regular string as an encryption key, something that is easy to come up with on-the-fly in JavaScript.

I'm not really in to crypto (can you tell?) but I've heard that RC4 is a rather weak algorithm. Sometime I'm going to look into possibly replacing it with a stronger private-key encryption method.

Usage Notes for Developers

For serious developers, RSAJAX should serve more as a proof-of-concept than an actual library. Here's why:

Encrypted AJAX calls involves more than just a library of functions. It involves something more like a framework. The source code available here works for developers that have a PHP framework, but not everybody has that. In fact, if I had been with a better web host at the time I wrote it, I probably would have written the server side of RSAJAX in a different language.

But even for PHP users, RSAJAX makes too many implementation decisions to really just be called a "library". Customizing them all to fit your web app will most likely result in nearly all of the code being rewritten!

For example, RSAJAX stores several values in the PHP session. It calls session_start() in order to ensure that those values are available. It also defines several global variables.

In short, just take RSAJAX as a proof-of-concept. It does work nicely if your web app is set up for it, but it's probably best that you re-code my methodology in your own way.