Java Tutorial/Security/Password Based Encryption
PBE File Encrypt
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.MessageDigest;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
public class MainClass {
public static void main(String[] args) throws Exception{
Cipher cipher = createCipher(Cipher.ENCRYPT_MODE);
applyCipher("file_to_encrypt", "encrypted_file", cipher);
cipher = createCipher(Cipher.DECRYPT_MODE);
applyCipher("file_to_decrypt", "decrypted_file", cipher);
}
static Cipher createCipher(int mode) throws Exception {
PBEKeySpec keySpec = new PBEKeySpec("test".toCharArray());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey key = keyFactory.generateSecret(keySpec);
MessageDigest md = MessageDigest.getInstance("MD5");
md.update("input".getBytes());
byte[] digest = md.digest();
byte[] salt = new byte[8];
for (int i = 0; i < 8; ++i)
salt[i] = digest[i];
PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 20);
Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
cipher.init(mode, key, paramSpec);
return cipher;
}
static void applyCipher(String inFile, String outFile, Cipher cipher) throws Exception {
CipherInputStream in = new CipherInputStream(new FileInputStream(inFile), cipher);
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(outFile));
int BUFFER_SIZE = 8;
byte[] buffer = new byte[BUFFER_SIZE];
int numRead = 0;
do {
numRead = in.read(buffer);
if (numRead > 0)
out.write(buffer, 0, numRead);
} while (numRead == 8);
}
}
PBE With SHA And Two fish
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import sun.misc.BASE64Decoder;
public class MainClass {
public static void main(String[] args) throws Exception {
System.out.println(decrypt(new char[] { "a", "b", "c", "d" }, "plaintext1234567890"));
}
private static String decrypt(char[] password, String text) throws Exception {
String salt = text.substring(0, 12);
String ciphertext = text.substring(12, text.length());
BASE64Decoder decoder = new BASE64Decoder();
byte[] saltArray = decoder.decodeBuffer(salt);
byte[] ciphertextArray = decoder.decodeBuffer(ciphertext);
PBEKeySpec keySpec = new PBEKeySpec(password);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithSHAAndTwofish-CBC");
SecretKey key = keyFactory.generateSecret(keySpec);
PBEParameterSpec paramSpec = new PBEParameterSpec(saltArray, 1000);
Cipher cipher = Cipher.getInstance("PBEWithSHAAndTwofish-CBC");
cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
return new String(cipher.doFinal(ciphertextArray));
}
}
Read the first 8 bytes of the ciphertext and use that as the salt
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import sun.misc.BASE64Encoder;
public class MainClass {
public static void main(String[] args) throws Exception {
System.out.println(encrypt(new char[] { "a", "b", "c", "d" }, "plaintext1234567890"));
}
private static String encrypt(char[] password, String plaintext) throws Exception {
byte[] salt = new byte[8];
Random random = new Random();
random.nextBytes(salt);
PBEKeySpec keySpec = new PBEKeySpec(password);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithSHAAndTwofish-CBC");
SecretKey key = keyFactory.generateSecret(keySpec);
PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 1000);
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;
}
}