Wednesday, January 25, 2012

Encrypting Transmissions between JavaScript and PHP Part 2: Making JavaScript encrypt the right thing using the right thing

So now that we have the keys from Part 1 we can start setting up the JavaScript portion of our party.  If you have done a search for "Javascript RSA" you have probably found several different libraries that will implement it for you.  Of particular note are:
https://ziyan.info/2008/10/javascript-rsa/ and http://www-cs-students.stanford.edu/~tjw/jsbn/
The former is a modified implementation of the latter.  For the sake of this post we are going to use the former. For my own personal use I modified the code a little bit to make it more readable and so I could understand it better, but it doesn't change the way anything works so I'm not going to include it unless anyone wants it.

You will want to download the files rsa.js and jsbn.js and include them on your web page the way you normally do such things (i.e. <script language="JavaScript" type="text/javascript" src="jsbn.js"> and <script language="JavaScript" type="text/javascript" src="rsa.js">).

First and foremost we need to set things up to use the key.  How do we read that into JavaScript? Nice and simple, we cut and paste.


var pem="-----BEGIN PUBLIC KEY-----\
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3sZto3ZI4vmtMv0Vx+Oa\
liJ/EeVnQ7R+rX8bya+zzoI/S2f7gD+K/xNK/AD6RZ0Q1dgJ8+Nl1N+DLyDzWvLo\
FTNbmNJeo+j3VM5I0xXpWeETMtRGcYysogZILprICezZM5CfC7awAh36xJD35v6m\
XkwWkAq2QShQDApMJyoFJI2x9DeDoRIwgMh5pWSaNsfFRJqGaNhWHPZNILkc/PfE\
eI3JZEjYO7+Bpdgo7VD5jbbPv7R1xtwko1IClhgPA3jizuQJQnaJL9G6T+MjStXG\
5mdfnz2oTKBOIFMzblHSlqOYDnhP7Jbh0x0xE5dPaQQ0fsMxJqWEkDNIcfhWv8Bk\
fQIDAQAB\
-----END PUBLIC KEY-----";
You will note the \ at the end of each line.  Since the key is so long you will most likely want to use a line break so you can have it on multiple lines.  I recommend not having any white space before or after the \.
Lest anyone worry about having the public key in the actual code, remember that it is the public key.  People are supposed to know it. You could theoretically have the server generate a new public key with each request and embed it in the JavaScript for you, but in my opinion there is very little reason to do so unless you are super hyper paranoid or are protecting something more exciting than a user's blog.  You can check out the PHP OpenSSL documentation if you would like to pursue something more in depth.

Next, we load the key into the library with:
var key = RSA.getPublicKey(pem);
Now things are ready to go.  The actual code to encrypt something is :
encryptedText=RSA.encrypt(stringToBeEncrypted, key);
 How you choose to go about implementing that is up to you since there are quite a few usable ways, but here is a simple example:


<SCRIPT>
function encryptData(){
element=document.getElementById('encryptMe');
element.value=RSA.encrypt(element.value, key);
}
</SCRIPT>
<FORM ACTION='decrypt.php' METHOD='POST' id='txtAuth' onsubmit='encryptData()'>";
<INPUT type='text' name='encryptMe' id='encryptMe'></INPUT>
<input name='txtSubmit' type='submit' id='txtSubmit' value='Submit'>"; </FORM>";

I hope that this will save someone some trouble! Here is Part 3!




3 comments:

SBL said...

Hey Jeff,

the link to ziyan appears broken, the newer link is http://www.ziyan.info/2008/10/javascript-rsa.html

and the updated source code can be downloaded from:

https://github.com/ziyan/javascript-rsa

SBL said...

another way to create the public key var in javascript is to use the append operator +=

var pem="";
pem += "-----BEGIN PUBLIC KEY-----";
pem += "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3sZto3ZI4vmtMv0Vx+Oa";
pem += "liJ/EeVnQ7R+rX8bya+zzoI/S2f7gD+K/xNK/AD6RZ0Q1dgJ8+Nl1N+DLyDzWvLo";

etc
until the full keylength is appended to the var.

this makes it easier to create from the plaintext file, and easier to read for troubleshooting.


Anonymous said...

I have problem with calling RSA.encrypt... the script just stop there... I tried to walkthru rsa.js but I couldn't figure out what the problem is..

Has anyone sucessfully implemented this? and appreciate if you can share the link for rsa.js and jsbn.js.... thanks