package com.jwx.commons.core.util;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.logging.Level;
import java.util.logging.Logger;
public class AESUtils {
private static final String CHARSET = "utf-8";
private static final String KEY_ALGORITHM = "AES";
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";//默认的加密算法
/**
* AES 加密操作
* @param content 待加密内容
* @param password 密钥 密钥(16位,java默认支持16位,其他长度需要第三方jar包)
* @param toLowerCase 返回的内容全小写,要大写时传false
* @return 返回16进制转码后的加密数据
*/
public static String encrypt(String content, String password, boolean toLowerCase) {
try {
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);// 创建密码器
byte[] byteContent = content.getBytes(CHARSET);
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(password));// 初始化为加密模式的密码器
byte[] result = cipher.doFinal(byteContent);// 加密
return HexUtils.encodeHexString(result,toLowerCase); //通过16进制转码返回
} catch (Exception ex) {
Logger.getLogger(AESUtils.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
/**
* AES 解密操作
* @param content 待解密的密文
* @param password 密钥(16位,java默认支持16位,其他长度需要第三方jar包)
* @return 明文
*/
public static String decrypt(String content, String password) {
try {
//实例化
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
//使用密钥初始化,设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, getSecretKey(password));
//执行操作
byte[] result = cipher.doFinal(HexUtils.decodeHex(content.toCharArray()));
return new String(result, CHARSET);
} catch (Exception ex) {
Logger.getLogger(AESUtils.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
/**
* 生成加密密钥
* @param password 密钥
* @return 密钥对象
*/
private static SecretKeySpec getSecretKey(final String password) {
return new SecretKeySpec(password.getBytes(), KEY_ALGORITHM);// 转换为AES专用密钥
}
public static void main(String[] args) {
String content = "abc123";
String pwd = "1234562019-08-25";
System.out.println("秘钥:" + pwd);
System.out.println("加密内容:" + content);
String encryptResult = AESUtils.encrypt(content, pwd, false);
System.out.println("加密结果:" + encryptResult);
System.out.println("解密后内容:" + AESUtils.decrypt(encryptResult.toUpperCase(), pwd));
}
}
package com.jwx.commons.core.util;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
/**
* 十六进制与字符串转换工具类
*
* @author ZENG.XIAO.YAN
* @version 1.0
* @Date 2019-08-24
*/
public class HexUtils {
/** 默认字符集 */
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
/** 小写的0-f */
private static final char[] DIGITS_LOWER =
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
/** 大写的0-F */
private static final char[] DIGITS_UPPER =
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
/** 字符集 */
private final Charset charset;
/*****************************构造方法 及相关get方法*************************************/
public HexUtils() {
// 默认使用utf-8
this.charset = DEFAULT_CHARSET;
}
public HexUtils(final Charset charset) {
this.charset = charset;
}
public HexUtils(final String charsetName) {
this(Charset.forName(charsetName));
}
/*****************************静态方法*************************************/
public static byte[] decodeHex(final String data) throws Exception {
return decodeHex(data.toCharArray());
}
public static byte[] decodeHex(final char[] data) throws Exception {
final int len = data.length;
// 字符数组的长度必须为偶数
if ((len & 0x01) != 0) {
throw new Exception("字符数组的长度必须为偶数");
}
final 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;
}
public static char[] encodeHex(final byte[] data) {
return encodeHex(data, true);
}
public static char[] encodeHex(final ByteBuffer data) {
return encodeHex(data, true);
}
public static char[] encodeHex(final byte[] data, final boolean toLowerCase) {
return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
}
public static char[] encodeHex(final ByteBuffer data, final boolean toLowerCase) {
return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
}
/**
* 最底层的encodeHex方法
* @param data
* @param toDigits
* @return
*/
private static char[] encodeHex(final byte[] data, final char[] toDigits) {
final int l = data.length;
// 长度乘2;因为一个byte为8位,转成16进制后为2位字符
final char[] out = new char[l << 1];
// two characters form the hex value.
for (int i = 0, j = 0; i < l; i++) {
// 高4位
out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
// 低4位
out[j++] = toDigits[0x0F & data[i]];
}
return out;
}
private static char[] encodeHex(final ByteBuffer data, final char[] toDigits) {
return encodeHex(data.array(), toDigits);
}
public static String encodeHexString(final byte[] data) {
return new String(encodeHex(data));
}
public static String encodeHexString(final byte[] data, final boolean toLowerCase) {
return new String(encodeHex(data, toLowerCase));
}
public static String encodeHexString(final ByteBuffer data) {
return new String(encodeHex(data));
}
public static String encodeHexString(final ByteBuffer data, final boolean toLowerCase) {
return new String(encodeHex(data, toLowerCase));
}
protected static int toDigit(final char ch, final int index) throws Exception {
final int digit = Character.digit(ch, 16);
if (digit == -1) {
throw new Exception("Illegal hexadecimal character " + ch + " at index " + index);
}
return digit;
}
/*****************************非静态方法*************************************/
public byte[] decode(final ByteBuffer buffer) throws Exception {
return decodeHex(new String(buffer.array(), getCharset()).toCharArray());
}
public byte[] encode(final ByteBuffer array) {
return encodeHexString(array).getBytes(this.getCharset());
}
/*****************************相关get方法*************************************/
public Charset getCharset() {
return this.charset;
}
public String getCharsetName() {
return this.charset.name();
}
@Override
public String toString() {
return super.toString() + "[charsetName=" + this.charset + "]";
}
}