Java Cryptography
age 11
String base64 = encoder.encode(raw);
System.out.println(base64);
}
else if (args[0].indexOf("d") != -1) {
cipher.init(Cipher.DECRYPT_MODE, key);
BASE64Decoder decoder = new BASE64Decoder();
byte[] raw = decoder.decodeBuffer(args[1]);
byte[] stringBytes = cipher.doFinal(raw);
String result = new String(stringBytes, "UTF8");
System.out.println(result);
}
}
}
SecretWriting has to generate a key the first time you use it. This can take a few seconds, so be
prepared to wait.
In the meantime, let's look at the steps in this program:
1. Check command-line arguments. We expect an option, either
-e or -d, and a string.
2. Next we need a key to use the cipher. We first attempt to deserialize the key from a file named
SecretKey.ser. If this fails, we need to create a new key. A
KeyGenerator object creates keys.
We obtain a
KeyGenerator by using a factory method, in just the same way that we obtained a
MessageDigest in the Masher example. In this case, we ask for a key for the DES (Data
Encryption Standard) cipher algorithm:
KeyGenerator generator = KeyGenerator.getInstance("DES");
The key generator must be initialized with a random number to produce a random new key. It
takes a few seconds to initialize the
SecureRandom, so be patient.
generator.init(new SecureRandom());
This done, we are set to generate a key. We serialize the key to the SecretKey.ser file so that
we can use the same key the next time we run the program.
3. Having obtained our key, we obtain a cipher in much the same way:
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
This specifies the DES algorithm and some other parameters the Cipher needs. We'll talk
about these in detail in Chapter 7.
4. Finally, we encrypt or decrypt the input data. The
Cipher is created in an uninitialized state; it
must be initialized, with a key, to either encryption mode or decryption mode. This is
accomplished by calling
init(). When encrypting, we take all of the command-line
arguments after the
-e option and concatenate them into one string, amalgam.
Then we get a byte array from this string and encrypt it in the call to
Cipher's doFinal()
method:
byte[] stringBytes = amalgam.getBytes("UTF8");
byte[] raw = cipher.doFinal(stringBytes);
Finally, as in the Masher example, we convert the raw encrypted bytes to base64 and display
them.
Decrypting is the same process in reverse. We convert the command-line argument from
base64 to an array of bytes. We then use our
Cipher object to decrypt this:
byte[] stringBytes = cipher.doFinal(raw);
We create a new String from the resulting byte array and display it. Note that we specify an
encoding for converting between a
String and a byte array. If we just used the default
encoding (by calling
getBytes() with no argument), then the ciphertext produced by this
program might not be portable from one machine to another. We use UTF8 as a standard
encoding because it can express all Unicode characters. For more information on UTF8, see
http://www.stonehand.com/unicode/standard/wg2n1036.html. You don't really have to
understand how UTF8 works; just think of it as a standard way to convert from a string to a
byte array and back.