/**
 * Encrypt the bytes using given password.
 * @param input the bytes that are intended to be encrypted
 * @param pwd the password
 * @return
 */
public static byte[] cryptEncrypt(byte[] input, String pwd) {
	javax.crypto.Cipher cipher = cryptGetCipher(pwd, false);
	byte[] result = null;
	try {
		result = cipher.doFinal(input);
	} catch (javax.crypto.IllegalBlockSizeException ex) {
		Ts.printErr(ex);
	} catch (javax.crypto.BadPaddingException ex) {
		Ts.printErr(ex);
	}
	return result;
}
 
/**
 * Decrypt the bytes using given password.
 * @param cipherText bytes that are intended to be decrypted
 * @param pwd the password
 * @return
 */
public static byte[] cryptDecrypt(byte[] cipherText, String pwd) {
	javax.crypto.Cipher cipher = cryptGetCipher(pwd, true);
	byte[] result = null;
	try {
		result = cipher.doFinal(cipherText);
	} catch (javax.crypto.IllegalBlockSizeException ex) {
		Ts.printErr(ex);
	} catch (javax.crypto.BadPaddingException ex) {
		Ts.printErr(ex);
	}
	return result;
}
 
/**
 * Common part for encryption and decryption.
 * @param pwd the password
 * @param isDecryption <tt>true</tt> if this method is for decryption and <tt>false</tt> if this is for encryption
 * @return
 */
private static javax.crypto.Cipher cryptGetCipher(String pwd, boolean isDecryption) {
	//--- Get the hash algorithm
	java.security.MessageDigest md5 = null;
	try {
		md5 = java.security.MessageDigest.getInstance("MD5");
	} catch (java.security.NoSuchAlgorithmException ex) {
		Ts.printErr(ex);
	}
	//--- Hash the pwd to make a 128bit key
	byte[] key = md5.digest(pwd.getBytes());
	//--- Create a key suitable for AES
	javax.crypto.spec.SecretKeySpec skey = new javax.crypto.spec.SecretKeySpec(key, "AES");
	javax.crypto.spec.IvParameterSpec ivSpec = new javax.crypto.spec.IvParameterSpec(md5.digest(key));
	javax.crypto.Cipher cipher = null;
	try {
		cipher = javax.crypto.Cipher.getInstance("AES/CTR/NoPadding", "SunJCE");
	} catch (java.security.NoSuchAlgorithmException ex) {
		Ts.printErr(ex);
	} catch (java.security.NoSuchProviderException ex) {
		Ts.printErr(ex);
	} catch (javax.crypto.NoSuchPaddingException ex) {
		Ts.printErr(ex);
	}
	try {
		if (isDecryption) {
			cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, skey, ivSpec);
		} else {
			cipher.init(javax.crypto.Cipher.DECRYPT_MODE, skey, ivSpec);
		}
	} catch (java.security.InvalidKeyException ex) {
		Ts.printErr(ex);
	} catch (java.security.InvalidAlgorithmParameterException ex) {
		Ts.printErr(ex);
	}
	return cipher;
}
 
/**
 * It is for validating whether the encryption and decryption work well.
 * It is also the example about how to encrypt and decrypt.
 * @param size the number of bytes that is encrypted and decrypted
 * @param password the password
 * @return <tt>true</tt> if the original bytes are equal to the bytes that is the result of encryption and decryption
 */
public static boolean cryptValidate(int size, String password) {
	byte[] bytes = new byte[size];
	r.nextBytes(bytes);
	byte[] byte_en = Ts.cryptEncrypt(bytes, password);
	byte[] byte_de = Ts.cryptDecrypt(byte_en, password);
	int diff = Ts.arrayCompare(bytes, byte_de, false);
	int diff2 = Ts.arrayCompare(bytes, byte_en, false);
	if (diff == 0 && diff2 != 0) {
		return true;
	} else {
		return false;
	}
}
 
/**
 * Compare two byte arrays.
 * @param orig
 * @param recon
 * @param isPrint
 * @return the number of bytes that are not equal.
 */
public static int arrayCompare(byte[] orig, byte[] recon, boolean isPrint) {
	int numError = 0;
	for (int i = 0; i < orig.length; i++) {
		if (orig[i] != recon[i]) {
			if (isPrint) {
				System.out.println("error on " + i + " :: " + orig[i] + " :: " + recon[i]);
			}
			numError++;
		}
	}
	if (isPrint) {
		System.out.println("number or error :: " + numError);
	}
	return numError;
}
 
public static void printErr(java.lang.Exception ex) {
	printErr(ex.getMessage());
}


Back to JavaHowTo

Alumni Liaison

EISL lab graduate

Mu Qiao