PBE Example Code
When decrypting, this program will read the first 8 bytes of the ciphertext and use that as the salt:
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.util.*;
// This is for BASE64 encoding and decoding
import sun.misc.*;
/**
* PBE.java
*/
If you're not using a Sun-based VM, comment out the import sun.misc.* line shown above, and
uncomment the following line. This will switch to our BASE64 encoders:
// import com.isnetworks.base64.*;
public class PBE
{
private static int ITERATIONS = 1000;
private static void usage()
{
System.err.println("Usage: java PBE -e|-d password text");
System.exit(1);
}
public static void main (String[] args)
throws Exception
{
if (args.length != 3) usage();
char[] password = args[1].toCharArray();
String text = args[2];
String output = null;
// Check the first argument: are we encrypting or decrypting?
if ("-e".equals(args[0])) output = encrypt(password, text);
else if ("-d".equals(args[0])) output = decrypt(password, text);
else usage();
System.out.println(output);
}
private static String encrypt(char[] password, String plaintext)
throws Exception
{
// Begin by creating a random salt of 64 bits (8 bytes)
byte[] salt = new byte[8];
Random random = new Random();
random.nextBytes(salt);
// Create the PBEKeySpec with the given password
PBEKeySpec keySpec = new PBEKeySpec(password);
// Get a SecretKeyFactory for PBEWithSHAAndTwofish
SecretKeyFactory keyFactory =
SecretKeyFactory.getInstance("PBEWithSHAAndTwofish-CBC");
// Create our key
SecretKey key = keyFactory.generateSecret(keySpec);
// Now create a parameter spec for our salt and iterations
PBEParameterSpec paramSpec = new PBEParameterSpec(salt, ITERATIONS);
// Create a cipher and initialize it for encrypting
Cipher cipher = Cipher.getInstance("PBEWithSHAAndTwofish-CBC");
cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
byte[] ciphertext = cipher.doFinal(plaintext.getBytes());
BASE64Encoder encoder = new BASE64Encoder();
String saltString = encoder.encode(salt);
String ciphertextString = encoder.encode(ciphertext);
return saltString+ciphertextString;
}
private static String decrypt(char[] password, String text)
throws Exception
{
// Below we split the text into salt and text strings.
String salt = text.substring(0,12);
String ciphertext = text.substring(12,text.length());
// BASE64Decode the bytes for the salt and the ciphertext
BASE64Decoder decoder = new BASE64Decoder();
byte[] saltArray = decoder.decodeBuffer(salt);
byte[] ciphertextArray = decoder.decodeBuffer(ciphertext);
// Create the PBEKeySpec with the given password
PBEKeySpec keySpec = new PBEKeySpec(password);
// Get a SecretKeyFactory for PBEWithSHAAndTwofish
SecretKeyFactory keyFactory =
SecretKeyFactory.getInstance("PBEWithSHAAndTwofish-CBC");
// Create our key
SecretKey key = keyFactory.generateSecret(keySpec);
// Now create a parameter spec for our salt and iterations
PBEParameterSpec paramSpec =
new PBEParameterSpec(saltArray, ITERATIONS);
// Create a cipher and initialize it for encrypting
Cipher cipher = Cipher.getInstance("PBEWithSHAAndTwofish-CBC");
cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
// Perform the actual decryption
byte[] plaintextArray = cipher.doFinal(ciphertextArray);
return new String(plaintextArray);
}
}
Running the Example
After compiling, we can run the example. For example, to encrypt we could type:
C:\> java PBE e sasquatch "Hello World!"
This will encrypt the string "Hello World!" using PBE with the password of "sasquatch". We should see
output similar to the following:
+xeivHEOb1M=AT/VYJlYIlJoQSMfKryaKw==
We can decrypt the output with:
C:\> java PBE d sasquatch "+xeivHEOb1M=AT/VYJlYIlJoQSMfKryaKw=="
and of course, we get our original message returned to us:
Hello World!
"Stop by in one week for the next installment!
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.