Created
January 8, 2020 04:35
-
-
Save hitesh-dhamshaniya/0a115cf6b75def2b72fe9f0b37bf1e70 to your computer and use it in GitHub Desktop.
This file contains 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 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