Knowing how and when to properly use security techniques is a skill that every Java ME developer needs to possess. Over the coming months (and years for that matter), an increasing number of mobile devices will support the Mobile Service Architecture (MSA) specification, which was a huge milestone for mobile devices. The MSA includes a bevy of mobile Java specifications, including the Security and Trust Services API (SATSA).
SATSA allows mobile developers to perform the following secure functions:- Encrypt and decrypt data using standard encryption algorithms like 3DES and AES
- Create, sign, and verify digital signatures
- Create symmetric and asymmetric keys
- Interact with the security element included on the mobile device
The encryption APIs built into SATSA (also known as SATSA-Crypto) is modeled after the encryption APIs built into the JDK 1.4, Thus, techniques that you learn in this tech tip can be used elsewhere.
In this tech tip, I’m going to assume that you have no background in encryption technologies. So let’s understand the difference between symmetric and asymmetric cryptography. Look at the following figure:
As you can see, in symmetric cryptography, the same key that encrypts your data is also the key that decrypts it. This facet of symmetric cryptography limits its use to a certain set of use cases. Symmetric cryptography is fine if you want to encrypt data for your own use, but it is definitely not a good solution if you need other people to send data securely to you. You can’t afford to have your security compromised, so sharing your symmetric key with other parties is not a good idea.
The following image, however, shows how asymmetric cryptography solves the problem:
With asymmetric cryptography, there are two keys involved instead of one. The first key (called the public key) can only secure or encrypt your data (it can never be used to decrypt the data). The second key (called the private key) can only be used to decrypt the data (and it can’t used to encrypt the data). For securing data for your own use, asymmetric cryptography is probably overkill. If you are communicating with several parties and they need to send data securely to you, however, then you can freely give them (or anyone else for that matter) your public key. It can be used only to encrypt data that can be decrypted only by you. You ,of course, keep the private key to yourself.
In this example, we are going to use 3DES symmetric encryption to show how to encrypt and decrypt some plain strings. Here’s how I create the key:
// 24 byte symmetric 3DES-EDE key
byte[] symKey = {
(byte) 0xca, (byte) 0x00, (byte) 0x25, (byte) 0x06,
(byte) 0x28, (byte) 0xae, (byte) 0xd2, (byte) 0xbd,
(byte) 0x2b, (byte) 0x7e, (byte) 0x15, (byte) 0x16,
(byte) 0x28, (byte) 0xae, (byte) 0xd2, (byte) 0xa6,
(byte) 0x2c, (byte) 0x7e, (byte) 0x10, (byte) 0x96,
(byte) 0x28, (byte) 0xff, (byte) 0xd2, (byte) 0xa6,
};
As you can see, I simply created a byte array of length 24 with an assortment of bytes to create my key. There is no special sequence needed, just an array of 24 bytes. In the example code, be sure to change byte values in this array to see how the key affects outcome of the encrypted text.
The following lines show how to create the actual Key and Cipher objects:
Key encryptionKey = new SecretKeySpec(symKey, 0, symKey.length, "DESede");
Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
As you can see, the last parameter in the SecretKeySpec constructor shows that an encryption algorithm must be supplied. I’ve already stated that I’m going to use the 3DES algorithm in this example, so I also have to supply the String that represents that encryption algorithm, “DESede”. The encryption algorithm must also be specified to get new instances from the Cipher class. In this case, however, I also had to specify the block character and padding modes. Once you have the key and Cipher, then encrypting data is a piece of cake:
cipher.init(Cipher.ENCRYPT_MODE, encryptionKey); byte[] ciphertext = new byte[ciphertextLength]; cipher.doFinal(messageBytes, 0, messageBytes.length, ciphertext, 0);
Decrypting data is also very easy; just change the Cipher mode:
cipher.init(Cipher.DECRYPT_MODE, encryptionKey); byte[] decrypted = new byte[messageBytes.length]; cipher.doFinal(ciphertext, 0, ciphertext.length, decrypted, 0);
The following complete working example runs on the Sun Wireless Toolkit for CLDC and also on SATSA-enabled mobile devices:
import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
public class EncryptionTest extends MIDlet implements CommandListener, Runnable {
// 24 byte symmetric 3DES-EDE key
byte[] symKey = {
(byte) 0xca, (byte) 0x00, (byte) 0x25, (byte) 0x06,
(byte) 0x28, (byte) 0xae, (byte) 0xd2, (byte) 0xbd,
(byte) 0x2b, (byte) 0x7e, (byte) 0x15, (byte) 0x16,
(byte) 0x28, (byte) 0xae, (byte) 0xd2, (byte) 0xa6,
(byte) 0x2c, (byte) 0x7e, (byte) 0x10, (byte) 0x96,
(byte) 0x28, (byte) 0xff, (byte) 0xd2, (byte) 0xa6,
};
private Display display;
private Form startForm;
private Command exitCommand;
public EncryptionTest() {
exitCommand = new Command("Exit", Command.EXIT, 0);
startForm = new Form("Encryption Example");
startForm.append("");
startForm.addCommand(exitCommand);
startForm.setCommandListener(this);
}
public void startApp() {
display = Display.getDisplay(this);
display.setCurrent(startForm);
Thread t = new Thread(this);
t.start();
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
public void commandAction(Command command, Displayable s) {
if (command == exitCommand) {
notifyDestroyed();
}
}
public void run() {
try {
encryptAndDecrypt("This is string with some text");
encryptAndDecrypt("ID: 2341234");
encryptAndDecrypt("PIN: 0001");
} catch (Exception e) {
System.out.println(e.toString());
}
}
private void encryptAndDecrypt(String plainText)
throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException,
InvalidKeyException, IllegalStateException, ShortBufferException,
IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
byte[] messageBytes = plainText.getBytes();
print("Plain text: " + plainText);
// Create the symmetric encryption Key
Key encryptionKey = new SecretKeySpec(symKey, 0, symKey.length, "DESede");
/* Construct Cipher class with name of the transformation algorithm */
Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
// Calculate ciphertext size.
int blocksize = 16;
int ciphertextLength = 0;
int remainder = messageBytes.length % blocksize;
if (remainder == 0) {
ciphertextLength = messageBytes.length;
} else {
ciphertextLength = messageBytes.length - remainder + blocksize;
}
System.out.println("ciphertext length: " + ciphertextLength);
cipher.init(Cipher.ENCRYPT_MODE, encryptionKey);
byte[] ciphertext = new byte[ciphertextLength];
cipher.doFinal(messageBytes, 0, messageBytes.length, ciphertext, 0);
print("Encrypted text: " + new String(ciphertext));
cipher.init(Cipher.DECRYPT_MODE, encryptionKey);
byte[] decrypted = new byte[messageBytes.length];
cipher.doFinal(ciphertext, 0, ciphertext.length, decrypted, 0);
print("the decrypted text is: " + new String(decrypted));
}
private void print(String s) {
startForm.append(s);
}
}
Bruce Hopkins is the author of the book, Bluetooth for Java (Apress Publishers), and is the creator of the JB-22 developer kit.
Hi,
I´ve found this post very helpfull to understand how to encrypt and decrypt data in J2ME, but I have one question:
Do you know some method to obtain the key from a given password instead of define it statically? I mean, do you know some method to do a Password-based encryption (PBE) with SATSA API?
Posted by David on February 14, 2008 at 07:36 AM PST #
3DES working on only netbeen ,not working on mobile
Posted by M.Alagar raja on February 14, 2008 at 10:48 PM PST #
David and all,
Although SATSA may not support PBE, the Bouncy Castle library for J2ME supports PBE:
http://www.bouncycastle.org/specifications.html
Thanks,
Bruce
Posted by Bruce Hopkins on February 15, 2008 at 11:30 AM PST #
hi
Posted by misho on March 29, 2008 at 12:40 AM PDT #
hellow
Posted by shatha on March 29, 2008 at 12:58 AM PDT #
alsalam alaikom
Posted by shatha on March 29, 2008 at 12:58 AM PDT #
Hi ,any one can help me to encrpt plain text 26 bit key in cipher text, and reverse.
i NEED a fullworking program in jsp or j2m3 or php ................................................thx
Posted by Muhammad Qasim Rafique on April 13, 2008 at 12:32 PM PDT #
Muhammad,
The code that I presented above in this Tech Tip shows how to encrypt and decrypt data using J2ME. What else are you looking for?
Thanks,
Bruce
Posted by Bruce Hopkins on April 15, 2008 at 01:14 PM PDT #