Created
December 19, 2018 03:34
-
-
Save arangates/4d4dbffcbe018b112eae2d5e3e314b48 to your computer and use it in GitHub Desktop.
AES encryption + decryption
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.UnsupportedEncodingException; | |
import java.security.MessageDigest; | |
import java.security.NoSuchAlgorithmException; | |
import java.util.Arrays; | |
import javax.crypto.Cipher; | |
import javax.crypto.spec.SecretKeySpec; | |
import javax.crypto.spec.IvParameterSpec; | |
import javax.crypto.SecretKey; | |
import javax.crypto.SecretKeyFactory; | |
import javax.crypto.spec.PBEKeySpec; | |
/** | |
* Aes encryption CAUTION : i am not crypto person jil jil jeevitha, take HEED!!! | |
* | |
* JIL JIL'S TODO: | |
* 1.optimize imports | |
* 2.remove unused code - sorry :D | |
* 3.find which MODE is most suited - seriously | |
* (https://stackoverflow.com/questions/1220751/how-to-choose-an-aes-encryption-mode-cbc-ecb-ctr-ocb-cfb) | |
* 4. Handle all exceptions gracefully eg: | |
* | |
* javax.crypto.IllegalBlockSizeException; | |
* javax.crypto.NoSuchPaddingException; | |
* java.security.InvalidAlgorithmParameterException; | |
* java.security.InvalidKeyException; | |
* | |
* 4.figure out why not to use filesystem, so that you can distribute keystore files instead of talking password | |
* 5. give me back my precious sleep,.. it is 4:33 a.m !!! ;( | |
* | |
* | |
* | |
* | |
* CREDITS: found around 3:12 in morning , helped good | |
* https://gist.github.com/easternHong/6ca75a7fdce15c6a23d3 | |
* | |
* REFERENCE: | |
* 1. https://www.devglan.com/online-tools/aes-encryption-decryption | |
* 2. https://aesencryption.net | |
* 3.https://stackoverflow.com/questions/992019/java-256-bit-aes-password-based-encryption- head first 4. | |
* 4.http://www.moserware.com/2009/09/stick-figure-guide-to-advanced.html - really cool one | |
* | |
* nOTES: Not sure why enterprises dont adapt spring framework at first place - | |
* https://docs.spring.io/spring-security/site/docs/3.1.x/reference/crypto.html | |
* couldve saved my night, you owe me a drink though | |
* | |
* | |
*/ | |
class AES { | |
// private static SecretKeySpec secretKey; | |
// private static byte[] key; | |
// private static byte[] decryptedString; | |
// private static byte[] encryptedString; | |
// public static void setKey(String myKey) { | |
// MessageDigest sha = null; | |
// try { | |
// key = myKey.getBytes("UTF-8"); | |
// System.out.println(key.length); | |
// sha = MessageDigest.getInstance("SHA-1"); | |
// key = sha.digest(key); | |
// key = Arrays.copyOf(key, 16); // use only first 128 bit | |
// System.out.println(key.length); | |
// System.out.println("Newly generated hash: "+new String(key, "UTF-8")+key); | |
// secretKey = new SecretKeySpec(key, "AES"); | |
// } catch (NoSuchAlgorithmException e) { | |
// e.printStackTrace(); | |
// } catch (UnsupportedEncodingException e) { | |
// e.printStackTrace(); | |
// } | |
// } | |
// public static byte[] getDecryptedString() { | |
// return decryptedString; | |
// } | |
// public static void setDecryptedString(byte[] decryptedString) { | |
// AES.decryptedString = decryptedString; | |
// } | |
// public static byte[] getEncryptedString() { | |
// return encryptedString; | |
// } | |
// public static void setEncryptedString(byte[] encryptedString) { | |
// AES.encryptedString = encryptedString; | |
// } | |
// public static byte[] encrypt(String strToEncrypt) { | |
// try { | |
// Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); | |
// IvParameterSpec ivParameterSpec = new | |
// IvParameterSpec(secretKey.getEncoded()); | |
// cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec); | |
// setEncryptedString(cipher.doFinal(strToEncrypt.getBytes("UTF-8"))); | |
// } catch (Exception e) { | |
// System.out.println("Error while encrypting: " + e.toString()); | |
// } | |
// return null; | |
// } | |
// public static String decrypt(byte[] strToDecrypt) { | |
// try { | |
// Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING"); | |
// IvParameterSpec ivParameterSpec = new | |
// IvParameterSpec(secretKey.getEncoded()); | |
// cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec); | |
// setDecryptedString(cipher.doFinal(strToDecrypt)); | |
// } catch (Exception e) { | |
// System.out.println("Error while decrypting: " + e.toString()); | |
// } | |
// return null; | |
// } | |
// public static void main(String args[]) { | |
// final String strToEncrypt = args[0]; | |
// final String strPssword = args[1]; | |
// AES.setKey(strPssword); | |
// AES.encrypt(strToEncrypt.trim()); | |
// System.out.println("String to Encrypt: " + strToEncrypt); | |
// System.out.println("Encrypted BYTE: " + AES.getEncryptedString()); | |
// final byte[] strToDecrypt = AES.getEncryptedString(); | |
// AES.decrypt(strToDecrypt); | |
// System.out.println("Decrypted BYTE : " + AES.getDecryptedString()); | |
// System.out.println("Decrypted value: " + new | |
// String(AES.getDecryptedString())); | |
// } | |
// WITH IV SPEC - CBC MODE | |
// public static void main(String[] args) { | |
// try{ | |
// //message to be encrypted | |
// final String message = args[0]; | |
// final String password = args[1]; | |
// // Here the magic numbers | |
// final int pswdIterations = 65536; | |
// final int keySize = 128; | |
// final byte[] saltBytes = {0, 1, 2, 3, 4, 5, 6}; | |
// SecretKeyFactory factory = | |
// SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); | |
// PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes, | |
// pswdIterations, keySize); | |
// SecretKey secretKey = factory.generateSecret(spec); | |
// SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); | |
// // Instantiate the cipher | |
// Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); | |
// IvParameterSpec ivParameterSpec = new | |
// IvParameterSpec(secretKey.getEncoded()); | |
// // Encrypt | |
// cipher.init(Cipher.ENCRYPT_MODE, secret, ivParameterSpec); | |
// byte[] encrypted = cipher.doFinal(message.getBytes()); | |
// System.out.println("Original string: " + message); | |
// System.out.println("Encrypted string: " + new String(encrypted)); | |
// System.out.println("Encrypted string(HEX): " + | |
// ByteArrayToHexString(encrypted)); | |
// // Decrypt | |
// cipher.init(Cipher.DECRYPT_MODE, secret, ivParameterSpec); | |
// byte[] decrypt_original = cipher.doFinal(encrypted); | |
// String decrypt_originalString = new String(decrypt_original); | |
// System.out.println("Decrypt string: " + decrypt_originalString); | |
// } catch (Exception e) { | |
// System.out.println("Error while encrypting: " + e.toString()); | |
// } | |
// } | |
public static String ByteArrayToHexString(byte[] bytes) { | |
final char[] hexArray = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; | |
char[] hexChars = new char[bytes.length * 2]; // Each byte has two hex characters (nibbles) | |
int v; | |
for (int j = 0; j < bytes.length; j++) { | |
v = bytes[j] & 0xFF; // Cast bytes[j] to int, treating as unsigned value | |
hexChars[j * 2] = hexArray[v >>> 4]; // Select hex character from upper nibble | |
hexChars[j * 2 + 1] = hexArray[v & 0x0F]; // Select hex character from lower nibble | |
} | |
return new String(hexChars); | |
} | |
/** | |
* Utility method to convert a hexadecimal string to a byte string. | |
* | |
* <p> | |
* Behavior with input strings containing non-hexadecimal characters is | |
* undefined. | |
* | |
* @param s String containing hexadecimal characters to convert | |
* @return Byte array generated from input | |
* @throws java.lang.IllegalArgumentException if input length is incorrect | |
*/ | |
// NOT USED , LEFT JUS IN CASE BECOMES USEFUL | |
public static byte[] HexStringToByteArray(String s) throws IllegalArgumentException { | |
int len = s.length(); | |
if (len % 2 == 1) { | |
throw new IllegalArgumentException("Hex string must have even number of characters"); | |
} | |
byte[] data = new byte[len / 2]; // Allocate 1 byte per 2 hex characters | |
for (int i = 0; i < len; i += 2) { | |
// Convert each character into a integer (base-16), then bit-shift into place | |
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16)); | |
} | |
return data; | |
} | |
// MOST UNSAFEEEEEEEEEEEEEEEEE ECB mode !!!! | |
public static void main(String[] args) { | |
try { | |
// message to be encrypted | |
final String message = args[0]; | |
final String password = args[1]; | |
// Here the magic numbers | |
final int pswdIterations = 65536; | |
final int keySize = 128; | |
final byte[] saltBytes = { 0, 1, 2, 3, 4, 5, 6 }; //not sure why we do this https://stackoverflow.com/questions/24971765/java-aes-decrypt-different-results-after-saved-and-decrypted-again | |
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); | |
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes, pswdIterations, keySize); | |
SecretKey secretKey = factory.generateSecret(spec); | |
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); | |
// Instantiate the cipher | |
Cipher cipher = Cipher.getInstance("AES"); | |
// Encrypt | |
cipher.init(Cipher.ENCRYPT_MODE, secret); | |
byte[] encrypted = cipher.doFinal(message.getBytes()); | |
System.out.println("Original string: " + message); | |
// System.out.println("Encrypted string: " + new String(encrypted)); | |
System.out.println("Encrypted string(HEX): " + ByteArrayToHexString(encrypted)); | |
// Decrypt | |
cipher.init(Cipher.DECRYPT_MODE, secret); | |
byte[] decrypt_original = cipher.doFinal(encrypted); | |
String decrypt_originalString = new String(decrypt_original); | |
System.out.println("Decrypt string: " + decrypt_originalString); | |
} catch (Exception e) { | |
System.out.println("Error while encrypting: " + e.toString()); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment