本文由Java实现AES加密算法的简单示例分享改编而来,在AES/CBC/PKCS5Padding加密模式基础上,新增分步加密解密操作,为保存解密结果并在日后读取解密做准备;此外,本文还添加BASE64编解码功能,便于存储且略微增高破解难度。
代码如下:
package blog.example;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class AesCryptTest {
public final String KEY_ALGORITHM = "AES";
public final String CIPHER_ALGORITHM_CBC = "AES/CBC/PKCS5Padding";
public SecretKey secretKey;
public Cipher cipher;
public static void main(String[] args) throws Exception {
AesCryptTest act = new AesCryptTest();
String originString = "誌不強者智不達,言不信者行不果。——Mo-tse";
// 加密数据
System.out.println("加密 数据: " + originString);
String enString = act.encode(originString);
System.out.println("\r\n-----------------------------------------------------------\r\n");
// 解密数据
String deString = act.decode(enString);
System.out.println("解密 结果: " + deString);
}
public String encode(String oriStr) throws Exception {
// secretKey = KeyGenerator.getInstance(KEY_ALGORITHM).generateKey();
KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM);
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(getIV());
// 根据密钥初始化密钥生成器
kgen.init(128, secureRandom);
secretKey = kgen.generateKey();
cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC);
cipher.init(Cipher.ENCRYPT_MODE, secretKey,
new IvParameterSpec(getIV()));// 使用*加密*模式初始化 密钥
// 加密数据
byte[] encByte = cipher.doFinal(oriStr.getBytes());
System.out.println("字符串数组 : " + Arrays.toString(oriStr.getBytes()));
System.out.println("加密后数组(编码前) : " + Arrays.toString(encByte));
// 编码,将由逗号、数字组成的字节数组转化为不易辨别的字符串
BASE64Encoder enc = new BASE64Encoder();
String encStr = enc.encode(encByte);
System.out.println("加密后数组(编码后) : " + encStr);
return encStr;
}
public String decode(String encStr) throws Exception {
// 解码,将字符串转化为可用于解密的字节数组
BASE64Decoder dec = new BASE64Decoder();
byte[] encByteArr = null;
try {
encByteArr = dec.decodeBuffer(encStr);
} catch (IOException e1) {
System.out.println("Exception In Decoder.");
}
System.out.println("解密前数组(解码前) : " + encStr);
System.out.println("解密前数组(解码后) : " + Arrays.toString(encByteArr));
/*
* KeyGenerator 生成aes算法密钥
*
* 如果采取①处语句直接为secretKey赋值,则会产生如下错误:
* javax.crypto.BadPaddingException: Given final block not properly padded
* 故采取②处方式。注:加密、解密方法应同时采取此方式
*/
// secretKey = KeyGenerator.getInstance(KEY_ALGORITHM).generateKey();//①
KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM);// ②↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(getIV());
// 根据密钥初始化密钥生成器
kgen.init(128, secureRandom);
secretKey = kgen.generateKey();// ②↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC);
cipher.init(Cipher.DECRYPT_MODE, secretKey,
new IvParameterSpec(getIV()));// 使用*解密*模式初始化 密钥
// 解密数据
byte[] decByte = cipher.doFinal(encByteArr);
System.out.println("解密后数组 : " + Arrays.toString(decByte));
return new String(decByte);
}
static byte[] getIV() {
String iv = "0123456789abcdef"; // IV length: must be 16 bytes long
return iv.getBytes();
}
}
运行截图:
注:编译过程可能提示“BASE64Encoder cannot be resolved to a type”,是由 BASE64Encoder找不到jar包 引起,解决方法为先移除JRE再添加JRE————
右键项目→Build Path→Configure Build Path...→JRE System Library[xxx]→Remove→Add Library→JRE System Library→next→选择你的JRE→Finish→OK.