Unlocking the Secrets of Java Cryptography Extensions: The Basics
Listing 3.2 shows the reverse process of grabbing the encrypted key from the file and decrypting the data file.
package com.dlt.developer.crypto;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.crypto.*;import java.security.Key;
import java.io.*;
/**
* @author David Thurmond
* An example of decrypting a text file using Data Encryption
* Standard encryption.
*/
public class DecryptFileExample {
public static void main(String[] args) throws Exception {
// First, create the encryption key...
System.out.println("Reading key from file...");
BufferedInputStream in =
new BufferedInputStream(new FileInputStream
("encrypted_key.txt"));
byte[] keyBytes = new byte[in.available()];
in.read(keyBytes);
System.out.println("Bytes read=" + keyBytes.length);
in.close();
SecretKeySpec skeySpec = new SecretKeySpec(keyBytes, "DES");
// Now, create the cipher object with appropriate parameters...
System.out.println("Decrypting file using DES/ECB/PKCS5Padding");
Cipher desCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
desCipher.init(Cipher.DECRYPT_MODE, skeySpec);
System.out.println("Reading encrypted file and decrypting...");
BufferedOutputStream outData =
new BufferedOutputStream(new FileOutputStream
("decrypted_data.txt"));
BufferedInputStream inData =
new BufferedInputStream(new FileInputStream
("encrypted_data.txt"));
while (inData.available() > 0) {
// Read the next chunk of bytes...
byte[] encryptedBytes = new byte[inData.available()];
inData.read(encryptedBytes);
// Now, decrypt them and write them to the encrypted file...
byte[] cleartextBytes = desCipher.update(encryptedBytes);
outData.write(cleartextBytes, 0, cleartextBytes.length);
} // while
outData.write(desCipher.doFinal());
inData.close();
outData.flush();
outData.close();
System.out.println("Done!");
} // main
}
Listing 3.2: DecryptFileExample.java
In Listing 3.2, the file encrypted_key.txt is read, and the key's raw bytes are retrieved and loaded into a key spec for use by the Cipher object:
FileInputStream("encrypted_key.txt"));
byte[] keyBytes = new byte[in.available()];
...Create the cipher object with the right decription...
...parameters and key spec...
SecretKeySpec skeySpec = new SecretKeySpec(keyBytes, "DES");
Cipher desCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
desCipher.init(Cipher.DECRYPT_MODE, skeySpec);
The remainder of the process is just the reverse of the previous example. Data is read from encrypted_data.txt, is decrypted by using the Cipher.update() and Cipher.doFinal() methods just as before, and is written out to decrypted_data.txt. Note that without the final invocation of doFinal(), a chunk of data would be missing at the end of the decrypted file. By examining decrypted_data.txt and cleartext.txt, the input to the file encryption program, you will see that the files are identical.
Password-Based Encryption
Although password-based encryption is not considered to be as secure as the secret-key encryption method shown above, it is probably the most commonly used method of encrypting and decrypting data. Listing 4.1 shows how to encrypt a file using a predetermined password, "mybigsecret". The password algorithm in this example uses a predetermined source of randomness, called a salt, and an iteration counter to determine a block size for the encryption, to make cracking the password a bit more difficult. In a real-world example, the salt and iteration counter might be determined based on some pre-determined agreement between the encrypting and decrypting parties, rather than being a hard-coded value.
package com.dlt.developer.crypto;
import javax.crypto.*;import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.*;
import java.io.*;
/**
* @author David Thurmond
* An example of encrypting a text file using password-based
* encryption.
*/
public class EncryptFilePasswordExample {
public static void main(String[] args) throws Exception {
PBEKeySpec pbeKeySpec;
PBEParameterSpec pbeParamSpec;
SecretKeyFactory keyFac;
// Salt
byte[] salt = {(byte)0x9f, (byte)0x33, (byte)0x4e, (byte)0xfe,
(byte)0xd4, (byte)0xee, (byte)0x12, (byte)0x54};
// Iteration count
int count = 17;
// Create PBE parameter set
pbeParamSpec = new PBEParameterSpec(salt, count);
char[] password = {'m', 'y', 'b', 'i', 'g', 's', 'e', 'c',
'r', 'e', 't'};
pbeKeySpec = new PBEKeySpec(password);
keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
// Create PBE Cipher
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
// Initialize PBE Cipher with key and parameters
pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);
System.out.println("Encrypting file using
DES/ECB/PKCS5Padding");
System.out.println("Reading cleartext file and encrypting...");
BufferedOutputStream outData =
new BufferedOutputStream(new FileOutputStream
("password_encrypted_data.txt"));
BufferedInputStream in =
new BufferedInputStream(new FileInputStream
("cleartext.txt"));
while (in.available() > 0) {
// Read the next chunk of bytes...
byte[] cleartextBytes = new byte[in.available()];
in.read(cleartextBytes);
// Now, encrypt them and write them to the encrypted file...
byte[] encryptedBytes = pbeCipher .update(cleartextBytes);
outData.write(encryptedBytes, 0, encryptedBytes.length);
} // while
// Take care of any pending padding operations
outData.write(pbeCipher .doFinal());
in.close();
outData.flush();
outData.close();
System.out.println("Done!");
} // main
}
Listing 4.1: EncryptFilePasswordExample.java



Solid state disks (SSDs) made a splash in consumer technology, and now the technology has its eyes on the enterprise storage market. Download this eBook to see what SSDs can do for your infrastructure and review the pros and cons of this potentially game-changing storage technology.