Skip to content

Instantly share code, notes, and snippets.

@riversun
Last active October 9, 2023 06:16
Show Gist options
  • Save riversun/ec98e7a8b6491db2049b to your computer and use it in GitHub Desktop.
Save riversun/ec98e7a8b6491db2049b to your computer and use it in GitHub Desktop.
[Java]Encrypt/Decrypt text to text by using 128bit AES for Java
/**
* Copyright 2006-2016 Tom Misawa(riversun.org@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package org.riversun;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* Encrypt/Decrypt text2text by using AES 128bit
*
* @author Tom Misawa (riversun.org@gmail.com)
*/
public class TextAESCrypter {
private static final String CRYPT_ALGORITHM = "AES";
private static final String PADDING = "AES/CBC/PKCS5Padding";
private static final String CHAR_ENCODING = "UTF-8";
private String mCryptKey;
private String mCryptIV;
public static void main(String[] args) {
// Eexample of TextAESCrypter
// source text
final String srcText = "I'm happy.";
// The cryptkey must be 16-character(=128bit) string
String cryptKey = "abcdefghijklmnop";
// The initialization vector must be 16-character(=128bit) string
String cryptIV = "0123456789012345";
// create crypter
final TextAESCrypter crypter = new TextAESCrypter();
// set keys
crypter.setCryptKey(cryptKey, cryptIV);
// do encrypt
String encryptedText = crypter.encrypt(srcText);
// show result
System.out.println("sourceText=" + srcText + " -> encryptedText=" + encryptedText + "\n");
System.out.println("encrypted-text=" + encryptedText + " -> decrypted-text(source text)=" + crypter.decrypt(encryptedText));
}
/**
* Set crypt key
*
* @param cryptKey16CharStr
* @param cryptInitializationVector16CharStr
*/
public void setCryptKey(String cryptKey16CharStr, String cryptInitializationVector16CharStr) {
mCryptKey = cryptKey16CharStr;
mCryptIV = cryptInitializationVector16CharStr;
checkKeys();
}
/**
* Encrypt text to encrypted-text
*
* @param text
* @return
*/
public String encrypt(String text) {
checkKeys();
if (text == null) {
return null;
}
String retVal = null;
try {
final SecretKeySpec key = new SecretKeySpec(mCryptKey.getBytes(CHAR_ENCODING), CRYPT_ALGORITHM);
final IvParameterSpec iv = new IvParameterSpec(mCryptIV.getBytes(CHAR_ENCODING));
final Cipher cipher = Cipher.getInstance(PADDING);
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
final byte[] encrypted = cipher.doFinal(text.getBytes(CHAR_ENCODING));
retVal = new String(encodeHex(encrypted));
} catch (Exception e) {
e.printStackTrace();
}
return retVal;
}
/**
* Decrypt encrypted-text
*
* @param text
* @return
*/
public String decrypt(String text) {
checkKeys();
if (text == null) {
return null;
}
String retVal = null;
try {
final SecretKeySpec secretKeySpec = new SecretKeySpec(mCryptKey.getBytes(CHAR_ENCODING), CRYPT_ALGORITHM);
final IvParameterSpec ivParameterSpec = new IvParameterSpec(mCryptIV.getBytes(CHAR_ENCODING));
final Cipher cipher = Cipher.getInstance(PADDING);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
final byte[] decrypted = cipher.doFinal(decodeHex(text.toCharArray()));
retVal = new String(decrypted, CHAR_ENCODING);
} catch (Exception e) {
e.printStackTrace();
}
return retVal;
}
/**
* Check if key is compliant
*/
private void checkKeys() {
if (mCryptKey == null || mCryptKey.length() != 16 || mCryptIV == null || mCryptIV.length() != 16) {
throw new RuntimeException("Please call setCryptKey before enctypt/decrypt and make sure that the length of the cryptKey16CharStr is 16 characters");
}
}
/**
*
* Converts an array of characters representing hexadecimal values into an
* array of bytes of those same values. The returned array will be half the
* length of the passed array, as it takes two characters to represent any
* given byte. An exception is thrown if the passed char array has an odd
* number of elements. <br>
* Portion of Apache Software Foundation
*
* @param data
* An array of characters containing hexadecimal digits
* @return A byte array containing binary data decoded from the supplied
* char array.
* @throws Exception
* Thrown if an odd number or illegal of characters is supplied
*
*
*/
private byte[] decodeHex(char[] data) throws Exception {
int len = data.length;
if ((len & 0x01) != 0) {
throw new Exception("Odd number of characters.");
}
byte[] out = new byte[len >> 1];
// two characters form the hex value.
for (int i = 0, j = 0; j < len; i++) {
int f = toDigit(data[j], j) << 4;
j++;
f = f | toDigit(data[j], j);
j++;
out[i] = (byte) (f & 0xFF);
}
return out;
}
/**
* Converts a hexadecimal character to an integer. <br>
* Portion of Apache Software Foundation
*
* @param ch
* A character to convert to an integer digit
* @param index
* The index of the character in the source
* @return An integer
* @throws Exception
* Thrown if ch is an illegal hex character
*/
private int toDigit(char ch, int index) throws Exception {
int digit = Character.digit(ch, 16);
if (digit == -1) {
throw new Exception("Illegal hexadecimal character " + ch + " at index " + index);
}
return digit;
}
/**
* Converts an array of bytes into an array of characters representing the
* hexadecimal values of each byte in order. The returned array will be
* double the length of the passed array, as it takes two characters to
* represent any given byte. <br>
* Portion of Apache Software Foundation
*
* @param data
* a byte[] to convert to Hex characters
* @param toDigits
* the output alphabet
* @return A char[] containing hexadecimal characters
*
*
*/
private char[] encodeHex(byte[] data) {
final char[] DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
int l = data.length;
char[] out = new char[l << 1];
// two characters form the hex value.
for (int i = 0, j = 0; i < l; i++) {
out[j++] = DIGITS[(0xF0 & data[i]) >>> 4];
out[j++] = DIGITS[0x0F & data[i]];
}
return out;
}
}
@riversun
Copy link
Author

Additional Information of AES in Java

If you want to use stronger key leng like 256bit AES.

Just edit the code with the following exception occurs,
java.security.InvalidKeyException: Illegal key size or default parameters

So,you should download following

Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files
http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

And
Extract file,
Copy local_policy.jar, US_export_policy.jar to [JAVA_INSTALLED_PATH]/lib/security/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment