class/src/main/java/security/aes/wx/WxMsgAESUtil.java
package security.aes.wx;
import lombok.extern.slf4j.Slf4j;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Base64;
@Slf4j
public class WxMsgAESUtil {
static Charset CHARSET = StandardCharsets.UTF_8;
/**
* 对明文进行加密.
*
* @param text 需要加密的明文
* @return 加密后base64编码的字符串
* @throws AesException aes加密失败
*/
static String encrypt(byte[] aesKey, String text) throws AesException {
ByteGroup byteCollector = new ByteGroup();
byte[] textBytes = text.getBytes(CHARSET);
// randomStr + networkBytesOrder + text + appid
byteCollector.addBytes(textBytes);
// ... + pad: 使用自定义的填充方式对明文进行补位填充
byte[] padBytes = PKCS7Encoder.encode(byteCollector.size());
byteCollector.addBytes(padBytes);
// 获得最终的字节流, 未加密
byte[] unencrypted = byteCollector.toBytes();
try {
// 设置加密模式为AES的CBC模式
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
// 取密钥的前16字节作为 iv 初始化向量
IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
// 加密
byte[] encrypted = cipher.doFinal(unencrypted);
// 使用BASE64对加密后的字符串进行编码
return Base64.getEncoder().encodeToString(encrypted);
} catch (Exception e) {
log.error("", e);
throw new AesException(AesException.EncryptAESError);
}
}
/**
* 对密文进行解密.
*
* @param text 需要解密的密文
* @return 解密得到的明文
* @throws AesException aes解密失败
*/
static String decrypt(byte[] aesKey, String text) throws AesException {
byte[] original;
try {
// 设置解密模式为AES的CBC模式
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec key_spec = new SecretKeySpec(aesKey, "AES");
IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
cipher.init(Cipher.DECRYPT_MODE, key_spec, iv);
// 使用BASE64对密文进行解码
byte[] encrypted = Base64.getDecoder().decode(text);
// 解密
original = cipher.doFinal(encrypted);
} catch (Exception e) {
log.error("", e);
throw new AesException(AesException.DecryptAESError);
}
String xmlContent;
try {
// 去除补位字符
byte[] bytes = PKCS7Encoder.decode(original);
xmlContent = new String(bytes, CHARSET);
} catch (Exception e) {
log.error("", e);
throw new AesException(AesException.IllegalBuffer);
}
return xmlContent;
}
}