mysql
SET block_encryption_mode = 'AES-128-CBC';
set @key='1234567890ABCDEF1234567890ABCDEF';
set @iv='1234567890ABCDEF';
select HEX(AES_encrypt('659C09DE',@key,@iv));
SELECT AES_DECRYPT(UNHEX(HEX(AES_encrypt('659C09DE',@key,@iv))),@key, @Iv);
java HUTOOL
package com.dy.weld.util;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* @author
* 密钥必须为16字节或者16字节的倍数的字节型数据。
* 明文必须为16字节或者16字节的倍数的字节型数据,如果不够16字节需要进行补全。
*/
@Slf4j
public class AesUtil {
private static AES aes = null;
/**
* 16字节
*/
private static String keyStr = "1234567890ABCDEF1234567890ABCDEF";// 为了和mysql统一,长度必须为32位
//长度为16位的盐值
private static final String IV_KEY = "1234567890ABCDEF";
static {
// 构建
//随机生成密钥
SecretKeySpec secretKeySpec = new SecretKeySpec(getBytes(keyStr, 16), SymmetricAlgorithm.AES.getValue());
IvParameterSpec ivParameterSpec = new IvParameterSpec(IV_KEY.getBytes());
aes = new AES(Mode.CBC, Padding.PKCS5Padding, secretKeySpec, ivParameterSpec);
}
/**
* 破解时密匙长度是规定了的
* 如果密匙长度有问题会报错:Key length not 128/192/256 bits.
* 意思就比如密匙长度不是16位 就会报错~
* 所以需要填充密匙长度
*
* @param s
* @param length
* @return
*/
private static byte[] getBytes(String s, int length) {
int fixLength = length - s.getBytes().length;
if (s.getBytes().length < length) {
byte[] S_bytes = new byte[length];
System.arraycopy(s.getBytes(), 0, S_bytes, 0, s.getBytes().length);
for (int x = length - fixLength; x < length; x++) {
S_bytes[x] = 0x00;
}
return S_bytes;
}
return s.getBytes();
}
/**
* 加密
*
* @param content 原文
* @return 加密后的密文
*/
public static String encryptHex(String content) {
if (StringUtils.isBlank(content)) {
return content;
}
try{
// 加密为16进制表示
return aes.encryptHex(content);
}catch (Exception e){
log.error("加密失败, 原文:{}", content, e);
return content;
}
}
/**
* 解密
*
* @param encryptHex 密文
* @return 解密后的原文
*/
public static String decryptHex(String encryptHex) {
// 解密为字符串
try {
if (StringUtils.isBlank(encryptHex)) {
return encryptHex;
}
return aes.decryptStr(encryptHex, CharsetUtil.CHARSET_UTF_8);
} catch (Exception e) {
log.error("解密失败, 原文:{}", encryptHex, e);
return encryptHex;
}
}
public static void main(String[] args) {
String content = "659C09DE";
log.info("content:{}", content);
// 加密为16进制表示
String encryptHex = encryptHex(content);
log.info("encryptHex:{}", encryptHex.toUpperCase());
// 解密为字符串
String decryptStr = decryptHex(encryptHex);
log.info("decryptStr:{}", decryptStr);
}
}
java AESUtil2 不用 hutool
package com.dy.weld.util;
/**
* @author DMM (暂时未用到)
* @Description
* @since 2023/8/7
*/
import cn.hutool.core.util.HexUtil;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Locale;
/**
*
* @author zhouzhou
* 2020-9-29 15:27:42
*
*/
public class AES256 {
public static final String AES_CBC_PKCS_5_PADDING = "AES/CBC/PKCS5Padding";
public static final String AES = "AES";
public static final String KEY_PWD = "1234567890ABCDEF1234567890ABCDEF";
public static final String IV_KEY = "1234567890ABCDEF";
/**
*
* @param clearText 明文
* @return base64的密文
* @throws Exception 很多异常
*/
public static String encrypt(String clearText) throws Exception {
byte[] rawKey = KEY_PWD.getBytes();
byte[] result = encrypt(rawKey, IV_KEY.getBytes(), clearText.getBytes());
return HexUtil.encodeHexStr(result).toUpperCase(Locale.ROOT);
}
/**
*
* @param keyBytes 密码文节数组
* @param iv 向量字节数组
* @param clearTextBytes 明文字节数组
* @return 密文字节数组
* @throws Exception 加密时的异常
*/
private static byte[] encrypt(byte[] keyBytes, byte[] iv, byte[] clearTextBytes) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, AES);
Cipher cipher = Cipher.getInstance(AES_CBC_PKCS_5_PADDING);
IvParameterSpec ivs = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivs);
return cipher.doFinal(clearTextBytes);
}
/**
*
* @param encrypted 密文
* @return 明文
* @throws Exception 很多异常
*/
public static String decrypt(String encrypted) throws Exception {
byte[] rawKey = KEY_PWD.getBytes();
byte[] enc = HexUtil.decodeHex(encrypted);
byte[] result = decrypt(rawKey, IV_KEY.getBytes(), enc);
return new String(result);
}
/**
*
* @param key 密码字节数组
* @param iv 向量字节数组
* @param encrypted 密文字节数组
* @return 明文字节数组
* @throws Exception 解密异常
*/
private static byte[] decrypt(byte[] key, byte[] iv, byte[] encrypted) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(key, AES);
Cipher cipher = Cipher.getInstance(AES_CBC_PKCS_5_PADDING);
IvParameterSpec ivs = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivs);
return cipher.doFinal(encrypted);
}
public static void main(String[] args) {
String content = "659C09DE";
System.out.println("明文:" + content);
try {
String encryptResult = AES256.encrypt(content);
System.out.println("密文:" + encryptResult);
String decryptResult = decrypt(encryptResult);
System.out.println("解密:" + decryptResult);
} catch (Exception e) {
e.printStackTrace();
}
// 3e1ccf8e01e99b2747839f6578bbdc2b
}
}