Skip to content

Instantly share code, notes, and snippets.

@hitesh-dhamshaniya
Created January 8, 2020 04:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hitesh-dhamshaniya/0a115cf6b75def2b72fe9f0b37bf1e70 to your computer and use it in GitHub Desktop.
Save hitesh-dhamshaniya/0a115cf6b75def2b72fe9f0b37bf1e70 to your computer and use it in GitHub Desktop.
import android.util.Base64;
import java.nio.ByteBuffer;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* AesCipher
* <p>Encode/Decode text by password using AES-128-CBC algorithm</p>
*/
public class AesCipher {
public static final int INIT_VECTOR_LENGTH = 16;
/**
* @see <a href="https://stackoverflow.com/questions/9655181/how-to-convert-a-byte-array-to-a-hex-string-in-java">how-to-convert-a-byte-array-to-a-hex-string</a>
*/
private final static char[] hexArray = "0123456789ABCDEF".toCharArray();
/**
* Encrypt input text by AES-128-CBC algorithm
*
* @param secretKey 16/24/32 -characters secret password
* @param plainText Text for encryption
* @return Encoded string or NULL if error
*/
public static String encrypt(String secretKey, String plainText) {
String initVector = null;
try {
// Check secret length
if (!isKeyLengthValid(secretKey)) {
throw new Exception("Secret key's length must be 128, 192 or 256 bits");
}
// Get random initialization vector
SecureRandom secureRandom = new SecureRandom();
byte[] initVectorBytes = new byte[INIT_VECTOR_LENGTH / 2];
secureRandom.nextBytes(initVectorBytes);
initVector = bytesToHex(initVectorBytes);
initVectorBytes = initVector.getBytes("UTF-8");
IvParameterSpec ivParameterSpec = new IvParameterSpec(initVectorBytes);
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
// Encrypt input text
byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));
ByteBuffer byteBuffer = ByteBuffer.allocate(initVectorBytes.length + encrypted.length);
byteBuffer.put(initVectorBytes);
byteBuffer.put(encrypted);
// Result is base64-encoded string: initVector + encrypted result
return Base64.encodeToString(byteBuffer.array(), Base64.DEFAULT);
} catch (Throwable t) {
t.printStackTrace();
// Operation failed
return null;
}
}
/**
* Decrypt encoded text by AES-128-CBC algorithm
*
* @param secretKey 16/24/32 -characters secret password
* @param cipherText Encrypted text
* @return Self object instance with data or error message
*/
public static String decrypt(String secretKey, String cipherText) {
try {
// Check secret length
if (!isKeyLengthValid(secretKey)) {
throw new Exception("Secret key's length must be 128, 192 or 256 bits");
}
// Get raw encoded data
byte[] encrypted = Base64.decode(cipherText, Base64.DEFAULT);
// Slice initialization vector
IvParameterSpec ivParameterSpec = new IvParameterSpec(encrypted, 0, INIT_VECTOR_LENGTH);
// Set secret password
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
// Trying to get decrypted text
String result = new String(cipher.doFinal(encrypted, INIT_VECTOR_LENGTH, encrypted.length - INIT_VECTOR_LENGTH));
// Return successful decoded object
return result;
} catch (Throwable t) {
t.printStackTrace();
// Operation failed
return null;
}
}
/**
* Check that secret password length is valid
*
* @param key 16/24/32 -characters secret password
* @return TRUE if valid, FALSE otherwise
*/
public static boolean isKeyLengthValid(String key) {
return key.length() == 16 || key.length() == 24 || key.length() == 32;
}
/**
* Convert Bytes to HEX
*
* @param bytes Bytes array
* @return String with bytes values
*/
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment