hey developers, this is my last project which was written on basis of last years programming, the goal is implementation of client-side/server-side encrypted communication which makes ssl certificates from authorities unnecessary.
this post will not turn your already coded web site into more secure, it's more about writing from scratch.
server-side in my case is java.
you need you javascript files to be loaded as a bundle. this may be done by creating a servlet which reads all you js files into a string, and returns the string with "text/javascript" content type. css as well, but this is less necessary.
the main idea of my project is:
1. the page is loaded and 5 javascript variables are injected the result of javascript servlet.
you code will look like:
var sessionid = "_sessionid_";
var ivin = "_ivin_";
var keyin = "_keyin_";
var ivout = "_ivout_";
var keyout = "_keyout_:
_sessionid_, _ivin_, _keyin_, _ivout_ and _keyout_ are keywords which should be replaced in the class of javascript servlet (on the fly) to 5 random strings.
_sessionid_ should be long string with numbers, uppercase and lowercase letters.
_ivin_ and _ivout_ should be similar so _sessionid_, but 16 bytes.
_keyin_ and _keyout_ should be similar to the above. but 32 bytes.
aes256 cbc encryption is used.
and now for the goal itself.
1. the page is loaded with 5 random variables in javascript.
2. next ajax request is simply an encrypted query string or json string, and it's encrypted with _ivin_ and _keyin_ bytes. "iv" in this case is "initialization vector" which is used for aes cbc encryption, and "key" is key. the response from the server-side is aes256 cbc encrypted with _ivout_ and _keyout_. the part of encrypted response are new:
_ivin_, _keyin_, _ivout_ and _ivout_
3. the encrypted message is decrypted in javascript and 4 variables of the above are stored client-side.
4. and the next ajax message from client-side to server-side is encrypted with new keys from the previous encrypted response.
so it's chaining.
without decrypting the first request, man in the middle will not decrypt the second, and without decrypting the second one he will not decrypt the third one.
notice that ssl connection is based on static certificate installed on the site's server. my tool does not use static variables: encryption keys are regenerated randomly per request.
so you need:
1. javascript: global ajax function, which is called with data parameters, and it encrypts them with ivin and keyin, whenever they came from, first time page load or last ajax response. the response is decrypted with ivout and keyout and necessary function is called to process them. additionally 2 parameters are passed to the server, besides your data. they are internal servlet name (encrypted) and sessionid (plain). sessionid is generated on the page load.
2. java: javascript servlet which reads js files from file system and replaces keywords with ivs, keys and sessionid.
3. java: guava cache. once javascript servlet receives it's call, 5 strings are stored with guava cache in session (it's lifetime should be infinite) object: ivin, keyin, ivout, keyout ans sessionid.
4. java: one servlet which is used as a target of all requests. internal servlet name is in the encrypted string, and once ivin and keyin are found in guava cache by sessionid, java code redirects the request to the internal servlet which name was passed from javascript. all the data is returned from internal servlets. every internal servlet should return new ivin, keyin, ivout and keyout strings. external access to internal servlets may be protected by whitelisting with nginx.
5. you must use once formatted json objects as a response from your servlets, as you have one global ajax functions in your javascript file.
notice that encrypting and decrypting with java is ok, but javascript is more sensitive. you should encrypt with cryptojs and decrypt with aesjs. once the response is decrypted you should remove illegal characters at the end of decrypted response. this is the way aesjs works, i didn't find any better solution. cryptojs in a case of decryption simply does not work.
thank you.
