Java tutorial
//package com.java2s; //License from project: Apache License import android.util.Base64; import android.util.Log; import java.io.UnsupportedEncodingException; import java.security.GeneralSecurityException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; public class Main { private static final String TAG = "AESCrypt"; private static final String AES_MODE = "AES/ECB/NoPadding"; private static final String CHARSET = "UTF-8"; private static final String HASH_ALGORITHM = "SHA-256"; private static final byte[] ivBytes = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; public static boolean DEBUG_LOG_ENABLED = false; private static int BLOCK_SIZE = 16; private static char PADDING = ' '; /** * Encrypt and encode message using 256-bit AES with key generated from password. * * * @param password used to generated key * @param message the thing you want to encrypt assumed String UTF-8 * @return Base64 encoded CipherText * @throws GeneralSecurityException if problems occur during encryption */ public static String encrypt(final String password, String message) { log("message", message); byte[] cipherText; try { final SecretKeySpec key = generateKey(password); cipherText = encrypt(key, ivBytes, nullPadString(message).getBytes(CHARSET)); //NO_WRAP is important as was getting \n at the end String encoded = Base64.encodeToString(cipherText, Base64.NO_WRAP); log("Base64.NO_WRAP", encoded); return encoded; } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (GeneralSecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } /** * More flexible AES encrypt that doesn't encode * @param key AES key typically 128, 192 or 256 bit * @param iv Initiation Vector * @param message in bytes (assumed it's already been decoded) * @return Encrypted cipher text (not encoded) * @throws GeneralSecurityException if something goes wrong during encryption */ public static byte[] encrypt(final SecretKeySpec key, final byte[] iv, final byte[] message) throws GeneralSecurityException { final Cipher cipher = Cipher.getInstance(AES_MODE); //IvParameterSpec ivSpec = new IvParameterSpec(iv); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] cipherText = cipher.doFinal(message); log("cipherText", cipherText); return cipherText; } private static void log(String what, byte[] bytes) { if (DEBUG_LOG_ENABLED) Log.d(TAG, what + "[" + bytes.length + "] [" + bytesToHex(bytes) + "]"); } private static void log(String what, String value) { if (DEBUG_LOG_ENABLED) Log.d(TAG, what + "[" + value.length() + "] [" + value + "]"); } /** * Generates SHA256 hash of the password which is used as key * * @param password used to generated key * @return SHA256 of the password */ private static SecretKeySpec generateKey(final String password) throws NoSuchAlgorithmException, UnsupportedEncodingException { final MessageDigest digest = MessageDigest.getInstance(HASH_ALGORITHM); //byte[] bytes = password.getBytes("UTF-8"); //digest.update(bytes, 0, bytes.length); byte[] key = password.getBytes(); //log("SHA-256 key ", key); SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); return secretKeySpec; } static String nullPadString(final String original) { String output = original; int remain = 0; try { remain = output.getBytes("UTF8").length % BLOCK_SIZE; } catch (UnsupportedEncodingException e) { e.printStackTrace(); } if (remain != 0) { remain = BLOCK_SIZE - remain; for (int i = 0; i < remain; i++) { output += PADDING; } } return output; } /** * Converts byte array to hexidecimal useful for logging and fault finding * @param bytes * @return */ private static String bytesToHex(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]; int v; for (int j = 0; j < bytes.length; j++) { v = bytes[j] & 0xFF; hexChars[j * 2] = hexArray[v >>> 4]; hexChars[j * 2 + 1] = hexArray[v & 0x0F]; } return new String(hexChars); } }