AES的基本要求是,采用对称分组密码体制,密钥长度的最少支持为128、192、256,分组长度128位。AES加密数据块分组长度必须为128比特,密钥长度可以是128比特、192比特、256比特中的任意一个(如果数据块及密钥长度不足时,会补齐)。AES加密有很多轮的重复和变换。大致步骤如下:1、密钥扩展(KeyExpansion),2、初始轮(Initial Round),3、重复轮(Rounds),每一轮又包括:SubBytes、ShiftRows、MixColumns、AddRoundKey,4、最终轮(Final Round),最终轮没有MixColumns。
AES算法模式有四种,ECB, CBC , CFB, OFB 。
AES key 生成:
/**
* 秘钥长度
*/
private static final int SECURE_KEY_LENGTH = 16;
private static final String IV_STRING = "16-Bytes--String";
public static byte[] getAESKey(String key)
throws UnsupportedEncodingException {
byte[] keyBytes;
keyBytes = key.getBytes("UTF-8");
byte[] keyBytes16 = new byte[SECURE_KEY_LENGTH];
System.arraycopy(keyBytes, 0, keyBytes16, 0,
Math.min(keyBytes.length, SECURE_KEY_LENGTH));
return keyBytes16;
}
AES 加密:
public static byte[] encrypt(String content, String secureKey) {
if (content == null) {
return null;
}
try {
// 获得密匙数据
byte[] rawKeyData = getAESKey(secureKey);
// 从原始密匙数据创建KeySpec对象
SecretKeySpec key = new SecretKeySpec(rawKeyData, "AES");
// Cipher对象实际完成加密操作
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// 用密匙初始化Cipher对象
byte[] initParam = IV_STRING.getBytes();
IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);
cipher.init(Cipher.ENCRYPT_MODE, key, ivParameterSpec);
// 正式执行加密操作
byte[] encryptByte = cipher.doFinal(content.getBytes());
return encryptByte;
}catch (UnsupportedEncodingException e){
e.printStackTrace();
}catch (NoSuchAlgorithmException e){
e.printStackTrace();
}catch (NoSuchPaddingException e){
e.printStackTrace();
}catch (InvalidAlgorithmParameterException e){
e.printStackTrace();
}catch (InvalidKeyException e){
e.printStackTrace();
}catch (IllegalBlockSizeException e){
e.printStackTrace();
}catch (BadPaddingException e){
e.printStackTrace();
}
return null;
}
AES 解密:
public static String decrypt(byte[] content, String secureKey) {
if (content == null) {
return null;
}
try {
// 获得密匙数据
byte[] rawKeyData = getAESKey(secureKey); // secureKey.getBytes();
// 从原始密匙数据创建一个KeySpec对象
SecretKeySpec key = new SecretKeySpec(rawKeyData, "AES");
// Cipher对象实际完成解密操作
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// 用密匙初始化Cipher对象
byte[] initParam = IV_STRING.getBytes();
IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);
cipher.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);
return new String(cipher.doFinal(content),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
AES加密后的数据,可以转换为Base64编码去显示
public static String encode(byte[] data) {
return Base64.encodeToString(data,Base64.NO_WRAP);
}
相对应的在AES 解密前,也要进行Base64解码
public static byte[] decode(String content) {
return Base64.decode(content,Base64.NO_WRAP);
}
项目地址:https://github.com/xiongliang120/EncryptionProject