How to write a Java and JavaScript compatible implementation of Tiny Encryption Algorithm to encrypt some data exchanged between navigator and Java application server.
License : Copyright Emeric Nasi, some rights reserved
This work is licensed under a Creative Commons Attribution 4.0 International License.
Introduction
I decided a few weeks ago to create my own Java "stealth malware" I called Bromo. This malware’s goal is to test and demonstrate Java security and insecurity in a corporate environment by targeting a Java application. For example an "evil" Jar that could be included by a developer.
I adapted Bromo to Web Application trojaning so that a distant attacker could control from anywhere via Firefox for example. The problem that occurred to me was to secure the communication between the attacker navigator and the Web server.
In this case I do not have the hand on the server, and I need to be as stealthy as possible. Moreover I need an encryption system that can prevent anyone (WAF and admins) from reading the content of the requests and responses I send to the malware.
That’s why it led me to use Javascript encryption.
In this article I do not describe the malware itself.
This article sections are :
- The encryption algorithm I chose
- The Java implementation of the algorithm
- The Javascript implementation of the algorithm
The difficulty here is to have compatible implementation between Java and Javascript (which is not a piece of cake).
I. Tiny Encryption Algorithm
Also called "TEA" or just "Tiny", the Tiny Encryption Algorithm was first presented in 1994 by David Wheeler and Roger Needham from Cambridge.
TEA encryption relies on a cipher operation that encrypts two 32bit Integers using a 4*32bits key.
This algorithm has two main assets. First it is not subject to any sort of patent or license, next it offers a strong cryptography in regard to the easiness of its implementation.
If you want to learn more about TEA, you should have a look at the TEA official page. This website presents a lot of TEA implementation and I relied heavily on it when I had to build my own Java and JavaScript implementation.
II. Java TEA implementation
II.1 About Java TEA implementation
The next Java TEA implementation is based on various TEA implementation you can find on the TEA official page. The main problem with a Java TEA implementation is the lack of "unsigned" types in the Java language. The TEA algorithm relies on fast shifting on unsigned 32-bits integers, and that is also the case for other language implementation. This suggests we will have a compatibility problem between Java and other language implementation.
Because we cannot force Java to use unsigned int we will have to use a classical Java TEA implementation, and force unsigned int usage on the other side (JavaScript implementation).
II.2 Utility functions
The Java implementation part is not a big problem, base 64 conversion, int[] to byte[] and other utility function can be found easily on the Internet.
You can always email me if you want the complete source codes.
II.3 The TEA cipher
TEA is mainly a cipher operating on blocks of 64 bits. The next encipher and decipher are very common to all language TEA implementations. However you can notice the use of the >>> operator witch is an unsigned right shift (all bits are shift from one position to the right, the left positions are filled with zeros).
II.4 Encryption/Decryption
The next functions are the entry point for the TEA algorithm.
The data en encode or decode is stored in an array of bytes.
III. JavaScript TEA implementation
III.1 About JavaScript TEA implementation
The goal of this implementation is to provide conversion functions between JavaScript strings and encrypted base64 strings. These base64 encrypted strings should be compatible with the Java implementation encrypted strings.
Even if there are a lot of good TEA JavaScript implementation on the Internet, none of them are "Java compliant". Remember, Java does not manage unsigned integers! The problem we have is that all JavaScript integer are unsigned by default. And all the existing TEA JavaScript implementation use unsigned integers (which is normal because TEA is supposed to be more efficient with unsigned integers).
My JavaScript TEA implementation is an extension of the JavaScript TEA implementation of Chris Veness.
Here is the code header :
III.2 Utility functions
Fist we need to define a set of utility functions that we will need in our TEA implementation.
In my JavaScript implementation I used Base64 and UFT-8 encoding/decoding functions. Because they are just a copy/past from the Chris Veness JavaScript TEA implementation, I will not describe them here. If you want to implement the same system as I did, you can get these functions source code here.
III.3 The TEA cipher
As in the Java implementation, the cipher functions are the heart of the encryption algorithm.
The Tea cipher and decipher functions take 2 integers and apply the cipher in part I.2.
III.4 Encryption/Decryption
These are the entry points of our JavaScript TEA implementation.
As you can see, encryption/decryption compatibility between language is not always something trivial. If you wonder why Java does not implement unsigned integers you can always have a look at that discussion on the stackoverflow Q&A.
Concerning JavaScript, there are a lot of implementation of encryption function out there but remember that JavaScript encryption is almost never a good solution, and that you have to deal with the problems of navigators compatibility and server language compatibility.
I did not post all the source code in this article, if you want to have the complete JavaScript or Java source you can email me at emeric.nasi[at]sevagas.com