/*
* Blaufish’s HMAC’ed and IV:ed encryptor/decryotor
*
* Some rights reserved;
*
*/
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.Mac;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.junit.Test;
public class TestIsATest {
private static final String HMAC_ALGORTIHM = ”HmacSHA1″;
@Test
public void test1() throws Exception {
SecureRandom rnd = new SecureRandom();
byte[] keybytes24 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24 };
byte[] iv = new byte[8];
rnd.nextBytes(iv);
testEncryption(keybytes24, iv, ”DESEDE”, ”/CBC/PKCS5Padding”);
}
@Test
public void test2() throws Exception {
SecureRandom rnd = new SecureRandom();
byte[] keybytes24 = new byte[24];
rnd.nextBytes(keybytes24);
byte[] iv = new byte[8];
rnd.nextBytes(iv);
testEncryption(keybytes24, iv, ”DESEDE”, ”/CBC/PKCS5Padding”);
}
@Test
public void test3() throws Exception {
SecureRandom rnd = new SecureRandom();
byte[] keybytes8 = new byte[8];
rnd.nextBytes(keybytes8);
byte[] iv = new byte[8];
rnd.nextBytes(iv);
testEncryption(keybytes8, iv, ”DES”, ”/CBC/PKCS5Padding”);
}
@Test
public void test4() throws Exception {
SecureRandom rnd = new SecureRandom();
byte[] keybytes16 = new byte[16];
rnd.nextBytes(keybytes16);
byte[] iv = new byte[16];
rnd.nextBytes(iv);
testEncryption(keybytes16, iv, ”AES”, ”/CBC/PKCS5Padding”);
}
@Test
public void test5() throws Exception {
SecureRandom rnd = new SecureRandom();
byte[] keybytes16 = new byte[16];
rnd.nextBytes(keybytes16);
byte[] iv = new byte[8];
rnd.nextBytes(iv);
testEncryption(keybytes16, iv, ”blowfish”, ”/CBC/PKCS5Padding”);
}
static void testEncryption(byte[] keybytes, byte[] iv,
final String algorithm, String algorithmModifiers)
throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException,
BadPaddingException, InvalidKeySpecException,
InvalidAlgorithmParameterException {
byte[] cleartext = ”This is just an example”.getBytes();
String encrypted = encrypt(keybytes, iv, cleartext, algorithm,
algorithmModifiers);
byte[] cleartext1 = decrypt(keybytes, encrypted, algorithm,
algorithmModifiers);
System.out.println(new String(cleartext1));
}
private static String encrypt(byte[] keybytes, byte[] iv, byte[] cleartext,
final String algorithm, String algorithmModifiers)
throws NoSuchAlgorithmException, InvalidKeyException,
NoSuchPaddingException, InvalidAlgorithmParameterException,
IllegalBlockSizeException, BadPaddingException {
SecretKey key = generateKey(keybytes, algorithm);
Mac mac = Mac.getInstance(HMAC_ALGORTIHM);
Cipher cipher;
cipher = Cipher.getInstance(algorithm + algorithmModifiers);
AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
byte[] ciphertext = cipher.doFinal(cleartext);
mac.init(key);
byte[] keyedDigest = mac.doFinal(cleartext);
TupleIvCiphertextMac icm = new TupleIvCiphertextMac(iv, ciphertext,
keyedDigest);
return icm.generateEncodedString();
}
private static byte[] decrypt(byte[] keybytes, String encryptedString,
final String algorithm, String algorithmModifiers)
throws NoSuchAlgorithmException, InvalidKeyException,
NoSuchPaddingException, InvalidAlgorithmParameterException,
IllegalBlockSizeException, BadPaddingException {
TupleIvCiphertextMac icm = new TupleIvCiphertextMac(encryptedString);
SecretKey key = generateKey(keybytes, algorithm);
Mac mac = Mac.getInstance(HMAC_ALGORTIHM);
Cipher cipher;
cipher = Cipher.getInstance(algorithm + algorithmModifiers);
AlgorithmParameterSpec paramSpec = new IvParameterSpec(icm.iv);
cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
byte[] cleartext = cipher.doFinal(icm.ciphertext);
mac.init(key);
byte[] keyedDigest = mac.doFinal(cleartext);
if (!Arrays.equals(keyedDigest, icm.mac)) {
throw new RuntimeException(”MAC failure”);
}
return cleartext;
}
private static SecretKey generateKey(byte[] keybytes, String algorithm)
throws NoSuchAlgorithmException, InvalidKeyException {
SecretKey secretKey = new SecretKeySpec(keybytes, algorithm);
if (algorithm.contains(”DES”)) {
SecretKeyFactory skf = SecretKeyFactory.getInstance(algorithm);
secretKey = skf.translateKey(secretKey);
}
return secretKey;
}
private static class TupleIvCiphertextMac {
private static final char FIELD_SEPARATOR = ‘:’;
byte[] iv;
byte[] ciphertext;
byte[] mac;
TupleIvCiphertextMac(byte[] iv, byte[] ciphertext, byte[] mac) {
this.iv = iv;
this.ciphertext = ciphertext;
this.mac = mac;
}
String generateEncodedString() {
String sIV = Base64.encodeBase64String(iv);
String sCiphertext = Base64.encodeBase64String(ciphertext);
String sMac = Base64.encodeBase64String(mac);
StringBuilder sb = new StringBuilder().append(sIV).append(
FIELD_SEPARATOR).append(sCiphertext)
.append(FIELD_SEPARATOR).append(sMac);
return sb.toString();
}
TupleIvCiphertextMac(String encodedString) {
int separator1 = encodedString.indexOf(FIELD_SEPARATOR);
int separator2 = encodedString.lastIndexOf(FIELD_SEPARATOR);
if (separator1 == separator2) {
throw new IllegalArgumentException();
}
String sIV = encodedString.substring(0, separator1 – 1);
String sCiphertext = encodedString.substring(separator1 + 1,
separator2 – 1);
String sMac = encodedString.substring(separator2 + 1);
iv = Base64.decodeBase64(sIV);
ciphertext = Base64.decodeBase64(sCiphertext);
mac = Base64.decodeBase64(sMac);
}
}
}
/*
* Blaufish’s HMAC’ed and IV:ed encryptor/decryptor
*
* Some rights reserved;
*
*/
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.Mac;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.junit.Test;
public class TestIsATest {
private static final String HMAC_ALGORTIHM = ”HmacSHA1″;
@Test
public void test1() throws Exception {
SecureRandom rnd = new SecureRandom();
byte[] keybytes24 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24 };
byte[] iv = new byte[8];
rnd.nextBytes(iv);
testEncryption(keybytes24, iv, ”DESEDE”, ”/CBC/PKCS5Padding”);
}
@Test
public void test2() throws Exception {
SecureRandom rnd = new SecureRandom();
byte[] keybytes24 = new byte[24];
rnd.nextBytes(keybytes24);
byte[] iv = new byte[8];
rnd.nextBytes(iv);
testEncryption(keybytes24, iv, ”DESEDE”, ”/CBC/PKCS5Padding”);
}
@Test
public void test3() throws Exception {
SecureRandom rnd = new SecureRandom();
byte[] keybytes8 = new byte[8];
rnd.nextBytes(keybytes8);
byte[] iv = new byte[8];
rnd.nextBytes(iv);
testEncryption(keybytes8, iv, ”DES”, ”/CBC/PKCS5Padding”);
}
@Test
public void test4() throws Exception {
SecureRandom rnd = new SecureRandom();
byte[] keybytes16 = new byte[16];
rnd.nextBytes(keybytes16);
byte[] iv = new byte[16];
rnd.nextBytes(iv);
testEncryption(keybytes16, iv, ”AES”, ”/CBC/PKCS5Padding”);
}
@Test
public void test5() throws Exception {
SecureRandom rnd = new SecureRandom();
byte[] keybytes16 = new byte[16];
rnd.nextBytes(keybytes16);
byte[] iv = new byte[8];
rnd.nextBytes(iv);
testEncryption(keybytes16, iv, ”blowfish”, ”/CBC/PKCS5Padding”);
}
static void testEncryption(byte[] keybytes, byte[] iv,
final String algorithm, String algorithmModifiers)
throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException,
BadPaddingException, InvalidKeySpecException,
InvalidAlgorithmParameterException {
byte[] cleartext = ”This is just an example”.getBytes();
String encrypted = encrypt(keybytes, iv, cleartext, algorithm,
algorithmModifiers);
byte[] cleartext1 = decrypt(keybytes, encrypted, algorithm,
algorithmModifiers);
System.out.println(new String(cleartext1));
}
private static String encrypt(byte[] keybytes, byte[] iv, byte[] cleartext,
final String algorithm, String algorithmModifiers)
throws NoSuchAlgorithmException, InvalidKeyException,
NoSuchPaddingException, InvalidAlgorithmParameterException,
IllegalBlockSizeException, BadPaddingException {
SecretKey key = generateKey(keybytes, algorithm);
Mac mac = Mac.getInstance(HMAC_ALGORTIHM);
Cipher cipher;
cipher = Cipher.getInstance(algorithm + algorithmModifiers);
AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
byte[] ciphertext = cipher.doFinal(cleartext);
mac.init(key);
byte[] keyedDigest = mac.doFinal(cleartext);
TupleIvCiphertextMac icm = new TupleIvCiphertextMac(iv, ciphertext,
keyedDigest);
return icm.generateEncodedString();
}
private static byte[] decrypt(byte[] keybytes, String encryptedString,
final String algorithm, String algorithmModifiers)
throws NoSuchAlgorithmException, InvalidKeyException,
NoSuchPaddingException, InvalidAlgorithmParameterException,
IllegalBlockSizeException, BadPaddingException {
TupleIvCiphertextMac icm = new TupleIvCiphertextMac(encryptedString);
SecretKey key = generateKey(keybytes, algorithm);
Mac mac = Mac.getInstance(HMAC_ALGORTIHM);
Cipher cipher;
cipher = Cipher.getInstance(algorithm + algorithmModifiers);
AlgorithmParameterSpec paramSpec = new IvParameterSpec(icm.iv);
cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
byte[] cleartext = cipher.doFinal(icm.ciphertext);
mac.init(key);
byte[] keyedDigest = mac.doFinal(cleartext);
if (!Arrays.equals(keyedDigest, icm.mac)) {
throw new RuntimeException(”MAC failure”);
}
return cleartext;
}
private static SecretKey generateKey(byte[] keybytes, String algorithm)
throws NoSuchAlgorithmException, InvalidKeyException {
SecretKey secretKey = new SecretKeySpec(keybytes, algorithm);
if (algorithm.contains(”DES”)) {
SecretKeyFactory skf = SecretKeyFactory.getInstance(algorithm);
secretKey = skf.translateKey(secretKey);
}
return secretKey;
}
private static class TupleIvCiphertextMac {
private static final char FIELD_SEPARATOR = ‘:’;
byte[] iv;
byte[] ciphertext;
byte[] mac;
TupleIvCiphertextMac(byte[] iv, byte[] ciphertext, byte[] mac) {
this.iv = iv;
this.ciphertext = ciphertext;
this.mac = mac;
}
String generateEncodedString() {
String sIV = Base64.encodeBase64String(iv);
String sCiphertext = Base64.encodeBase64String(ciphertext);
String sMac = Base64.encodeBase64String(mac);
StringBuilder sb = new StringBuilder().append(sIV).append(
FIELD_SEPARATOR).append(sCiphertext)
.append(FIELD_SEPARATOR).append(sMac);
return sb.toString();
}
TupleIvCiphertextMac(String encodedString) {
int separator1 = encodedString.indexOf(FIELD_SEPARATOR);
int separator2 = encodedString.lastIndexOf(FIELD_SEPARATOR);
if (separator1 == separator2) {
throw new IllegalArgumentException();
}
String sIV = encodedString.substring(0, separator1 – 1);
String sCiphertext = encodedString.substring(separator1 + 1,
separator2 – 1);
String sMac = encodedString.substring(separator2 + 1);
iv = Base64.decodeBase64(sIV);
ciphertext = Base64.decodeBase64(sCiphertext);
mac = Base64.decodeBase64(sMac);
}
}
}