# AES Pkcs7加密/解密工具类,支持密钥偏移量
# Java代码
package com.guitu18.common.utils;
import cn.hutool.core.util.HexUtil;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Arrays;
/**
* AES Pkcs7加密/解密工具类,支持密钥偏移量
* <p>
* 介于java 不支持PKCS7Padding,只支持PKCS5Padding,但是PKCS7Padding和PKCS5Padding没有什么区别
* 要实现在java端用PKCS7Padding填充,需要用到bouncycastle组件来实现
* 代码参考:https://www.cnblogs.com/chen-lhx/p/6233954.html(有修改)
*
* @author zhangkuan
* @date 2020/5/4
*/
public class AesPkcs7Util {
/**
* 算法名称
*/
final String KEY_ALGORITHM = "AES";
/**
* 加解密算法/模式/填充方式
*/
final String algorithmStr = "AES/CBC/PKCS7Padding";
private static SecretKey key;
private static AlgorithmParameterSpec iv;
private Cipher cipher;
public AesPkcs7Util(String keyStr, String ivStr) {
// 如果密钥不足16位,那么就补足. 这个if 中的内容很重要
byte[] keyBytes = keyStr.getBytes();
int base = 16;
if (keyBytes.length % base != 0) {
int groups = keyBytes.length / base + 1;
byte[] temp = new byte[groups * base];
Arrays.fill(temp, (byte) 0);
System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
keyBytes = temp;
}
// 初始化
Security.addProvider(new BouncyCastleProvider());
// 转化成JAVA的密钥格式
key = new SecretKeySpec(keyBytes, KEY_ALGORITHM);
iv = new IvParameterSpec(ivStr.getBytes());
try {
// 初始化cipher
cipher = Cipher.getInstance(algorithmStr, "BC");
} catch (NoSuchAlgorithmException | NoSuchPaddingException | NoSuchProviderException e) {
e.printStackTrace();
}
}
/**
* 加密方法
*
* @param content 要加密的字符串
*/
public byte[] encrypt(byte[] content) {
byte[] encryptedText = null;
try {
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
encryptedText = cipher.doFinal(content);
} catch (Exception e) {
e.printStackTrace();
}
return encryptedText;
}
/**
* 解密方法
*
* @param encryptedData 要解密的字符串
*/
public byte[] decrypt(byte[] encryptedData) {
byte[] encryptedText = null;
try {
cipher.init(Cipher.DECRYPT_MODE, key, iv);
encryptedText = cipher.doFinal(encryptedData);
} catch (Exception e) {
e.printStackTrace();
}
return encryptedText;
}
public static void main(String[] args) {
AesPkcs7Util aes = new AesPkcs7Util("625202f9149guitu", "5efd3f60608guitu");
String content = "encryptedData 要解密的字符串";
byte[] enc = aes.encrypt(content.getBytes());
String hexStr = HexUtil.encodeHexStr(enc);
System.out.println("加密后的内容:" + hexStr);
byte[] dec = aes.decrypt(HexUtil.decodeHex(hexStr));
System.out.println("解密后的内容:" + new String(dec));
}
}
# JavaScript代码
使用之前需要引入 crypto-js.js,源码地址:https://github.com/brix/crypto-js
// 十六位十六进制数作为密钥
const key = CryptoJS.enc.Utf8.parse("625202f9149guitu");
//十六位十六进制数作为密钥偏移量
const iv = CryptoJS.enc.Utf8.parse('5efd3f60608guitu');
//解密方法
function decrypt(word) {
let encryptedHexStr = CryptoJS.enc.Hex.parse(word);
let srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
let decrypt = CryptoJS.AES.decrypt(srcs, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
return decryptedStr.toString();
}
//加密方法
function encrypt(word) {
let srcs = CryptoJS.enc.Utf8.parse(word);
let encrypted = CryptoJS.AES.encrypt(srcs, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
return encrypted.ciphertext.toString();
}
// Test
var encryptStr = encrypt('encryptedData 要解密的字符串');
console.log(encryptStr);
var decryptStr = decrypt(encryptStr);
console.log(decryptStr);