Javascript RSA Encryption and Java Decryption

Many of us have been working with Javascript since long time but when ever i ask people how to send encrypted data, the only answer is to use SSL . But this article shows how to send encrypted data even when we don’t have ssl enabled. This can come in to handy in many scenario’s

I used jCryption and Javascript Library to encrypt in Javascript and BouncyCastle Library on Javabackend to decypt,

Here is the flow in the example

  1. First Generate  RSA keys on server end ( Store in session).
  2. Send public key to client (javascript)
  3. Store keys in javascript variable
  4. In All subsequent requests use this key to encrypt data and send to server
  5. Use keys stored in session  to decrypt data and send response to server

Keys generation utility class in Java

package com.linkwithweb.encryption;

import java.io.IOException;
import java.security.KeyPair;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class EncryptionServlet
 */
public class EncryptionServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * Default constructor.
	 */
	public EncryptionServlet() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void service(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		if (request.getParameter("generateKeypair") != null) {

			JCryptionUtil jCryptionUtil = new JCryptionUtil();

			KeyPair keys = null;
			if (request.getSession().getAttribute("keys") == null) {
				keys = jCryptionUtil.generateKeypair(512);
				request.getSession().setAttribute("keys", keys);
			}

			StringBuffer output = new StringBuffer();

			String e = JCryptionUtil.getPublicKeyExponent(keys);
			String n = JCryptionUtil.getPublicKeyModulus(keys);
			String md = String.valueOf(JCryptionUtil.getMaxDigits(512));

			output.append("{\"e\":\"");
			output.append(e);
			output.append("\",\"n\":\"");
			output.append(n);
			output.append("\",\"maxdigits\":\"");
			output.append(md);
			output.append("\"}");

			output.toString();
			response.getOutputStream().print(
					output.toString().replaceAll("\r", "").replaceAll("\n", "")
							.trim());
		} else {
			response.getOutputStream().print(String.valueOf(false));
		}
	}

}

All client code is there in index.jsp and framework.js

Javascript Function that gets keys from server and stores in javascript variable

/**
 * Get Security keys from server so that we can encrypt request in future
 */
function getKeys() {
	$.jCryption.getKeys("EncryptionServlet?generateKeypair=true", function(
			receivedKeys) {
		keys = receivedKeys;
	});
}

On login button clicked here is how you encrypt and send request to server

/**
 * Called on Login Button clicked
 */
function onLoginButtonClicked() {
	var user = $("#login_user").val();
	var password = $("#login_password").val();
	$.jCryption.encrypt(user, keys, function(encrypted) {
		encryptedUser = encrypted;
		$.jCryption.encrypt(password, keys, function(encryptedPasswd) {
			encryptedPassword = encryptedPasswd;
			/**
			 * As both userName and password are encrypted now Submit login
			 */
			submitLoginRequest();
		});
	});
}

/**
 * Submit Login request
 */
function submitLoginRequest() {
	sendAjaxRequest("LoginServlet", {
		username : encryptedUser,
		password : encryptedPassword
	}, function(data) {
		if (data.length > 0) {
			$("#login_status").empty();
			$("#login_status").append(data);
		}
	});
}

And below is svn URL to download sample source code  https://linkwithweb.googlecode.com/svn/trunk/Utilities/jCryptionTutorial

Next version of tutorial will be from flex to java. Njoy reading and playing with Encryption code

18 thoughts on “Javascript RSA Encryption and Java Decryption

  1. One small question, will this application work without jCryption.jsp ? I mean, as far as I can see, the functionality is well served by the rest of the code. I don’t see a point of using so much scriptlet (java) in jsp..

  2. hi I had tried to use this code but it is giving error please help me.
    In mozilla “c is undefined.” for jQuery.jCryption-1.1.min.js

  3. I tried this code and it worked for me but the decrypted value has some special chars at the end. How to remove those special characters?

  4. Hi.
    I need help.
    1.
    In mozilla i am getting same error someone said here before:
    “c is undefined.” for jQuery.jCryption-1.1.min.js

    2.
    Other error I get is a NullPointerException

    java.lang.NullPointerException
    	com.linkwithweb.encryption.JCryptionUtil.getPublicKeyExponent(JCryptionUtil.java:158)
    	com.linkwithweb.encryption.EncryptionServlet.service(EncryptionServlet.java:42)
    	javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    

    note The full stack trace of the root cause is available in the Apache Tomcat

    I would apreciate any help.
    Tks.

  5. Hi, It’s really a good example, only the thing is encrypted string is too large, when it saved in history it appear on the password field which is very large where user will be conflicted.
    can you please provide solution for this stuff, I would appreciate your help.
    Tks.

  6. Very helpful post. Just a question, is this secured enough from preventing sniffers to access the private key? Please correct me if my understanding is wrong, i’m newbie on this.

    • Private is generated at runtime and stored in session or some storage in server.. We should schedule refreshing keys for a given time interval.. .. Yes as this is standard RSA encryption it is secure..

  7. Is there any working example using jcryption 3.0. I have to encrypt request using public key, and it will be decrypted in java at server side.I did google a lot but it showing only with PHP.
    Thanks…

  8. In the last step “5. Use keys stored in session to decrypt data and send response to server”, how can I make this work across different sessions ? Assume you have a signup form, you encrypt a password using Key 1 and store the encrypted password on your persistent store on the server. Now, after two days, the user logs in through the client. Wouldn’t I get a different KeyPair’s public key ? I used the following approach: Have a onetime generated key pair stored in a file on the server. Use this across sessions.
    Is this correct ? Do you see any security loopholes in this approach ?

    • There are different takes here..
      1) Have a single key pair generated and use that always for that user..
      2) Generate a new key pair when ever user does login to server and then use that for your session.

      I prefer first way..

      This is flow..

      First request always before login is getting public key from server..(Keys can be refreshed on server as per schedule)
      All subsequent request use the key to encrypt and send data.

      Hope this helps

  9. Thanks for the wonderful article, helped me a lot, This is working perfect with every browser,
    I added the ajax call to generate Public key on onload of Page,and used this public key to encrypt my data while submitting, sometimes when user calling on Iphone, AJAX call to generate public key call is not getting callled and that’s why Form data is not getting encrypted, do u have any clue, why sometimes it happend on Iphone? Thnaks a lot

Leave a reply to Vijay Sharma Cancel reply