Title: Professional Java Security
ISBN: 1861004257
US Price: $ 49.99
Canadian Price:
C$ 74.95
UK Price: £ 39.99
© Wrox Press Limited, US and UK.

Reviews : Java Books :
Professional Java Security : Symmetric Encryption

Applications

Symmetric encryption can be applied in quite a number of areas. It is much faster than asymmetric, or public-key encryption (sometimes by a factor of 1000) and for that reason it is recommended in situations where lots of data must be transformed. File encryption, network encryption, and database encryption are all good places to employ symmetric encryption. Its main weakness is the symmetry of the key. That same key must be used to encrypt and decrypt, so anyone with the ability to encrypt also has the ability to decrypt. If you are sending a symmetrically encrypted message, both sender and receiver must agree on a key in advance. For that reason, it is often best to use symmetric encryption to encrypt a large amount of data, and then encrypt the symmetric key with asymmetric encryption. We will investigate that further in the next chapter. For now, let's begin with a simple example – encrypting and decrypting a string.

The only JCE classes our code will use are the (javax.crypto.*) classes, which are used to handle cryptography. This makes the programs portable to any provider that supports the algorithms we use. We've discussed some of these classes in the previous chapter, but now let's investigate them in more depth along with the java.security.Key class.

javax.crypto.Cipher

The cipher is essentially the engine that performs the encryption and decryption of data. The Cipher class has four methods that we're interested in right now: getInstance(), init(), update(), and doFinal(). Let's go over them one by one:

getInstance()

As we've mentioned before, most of the classes in the JCE use factory methods instead of normal constructors. Rather than create an instance with the new keyword, we make a call to the class's getInstance() method, with the name of the algorithm and some additional parameters like so:

	Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");

The first parameter is the name of the algorithm, in this case, "DESede". The second is the mode the cipher should use, "ECB", which stands for Electronic Code Book. The third parameter is the padding, specified with "PKCS5Padding". We'll go into more detail about the mode and padding later. For now, just be aware that even though it is possible to skip the declaration of the mode and padding they should be declared anyway. If the mode and padding are skipped, the provider picks a mode and padding to use, which is rarely what you want, and prevents the code from being ported to other providers.

init()

Once an instance of Cipher is obtained, it must be initialized with the init() method. This declares the operating mode, which should be either ENCRYPT_MODE or DECRYPT_MODE, and also passes the cipher a key (java.security.Key, described later). Assuming we had a key declared, initialized, and stored in the variable myKey, we could initialize a cipher for encryption with the following line of code:

	cipher.init(Cipher.ENCRYPT_MODE, myKey);

The JCE 1.2.1 specification adds two more possible operating modes, WRAP_MODE and

UNWRAP_MODE
. These modes set up a cipher to encrypt or decrypt keys. We'll use these modes later, when we use asymmetric encryption.

update()

In order to actually encrypt or decrypt anything, we need to pass it to the cipher in the form of a byte array. If the data is in the form of anything other than a byte array, it needs to be converted. If we have a string called myString and we want to encrypt it with the cipher we've initialized above, we can do so with the following two lines of code:

	byte[] plaintext = myString.getBytes("UTF8");
	byte[] ciphertext = cipher.update(plaintext);

Ciphers typically buffer their output. If the input is large enough that it produces some ciphertext, it will be returned as a byte array. If the buffer has not been filled, then null will be returned.

Note that in order to get bytes from a string, we should specify the encoding method. In most cases, it will be UTF8.

If you don't specify the encoding type, you will get the underlying platform's default encoding. This is almost never what you want, and can cause bizarre errors when encryption takes place on one platform, and decryption on another. Always specify the encoding.

doFinal()

Now we can actually get the encrypted data from the cipher. doFinal() will produce a byte array, which is the encrypted data.

	byte[] ciphertext = cipher.doFinal();

A number of the methods we've talked about can be overloaded with different arguments, like start and end indices for the byte arrays passed in. We're not going to go into detail covering them, as they are presented clearly in the JCE's JavaDoc.

How to Add Java Applets to Your Site

New on the Java Boutique:

New Review:

Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling API boasts simplicity, ease-of-integration, a well-rounded feature set, and it's free!

New Applet:

Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA sequences into three useful formats.

Elsewhere on internet.com:

WebDeveloper Java
Lots of Java information on webdeveloper.com

WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.

ScriptSearch Java
Hundreds of free Java code files to download.

jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.