完美的跟JS版本的AES加密库兼容
package com.wang.common.util;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidParameterSpecException;
import java.util.UUID;
/**
* @version 1.0
* @author: 青蛙
* @date : 2019-01-22
*/
public class AESUtil {
private static Boolean initialized = false;
public static final String AES_ECB_PKCS7_PADDING = "AES/ECB/PKCS7Padding";
public static final String AES_CBC_PKCS7_PADDING = "AES/CBC/PKCS7Padding";
public static final String AES_ECB_PKCS5_PADDING = "AES/ECB/PKCS5Padding";
public static final String AES_CBC_PKCS5_PADDING = "AES/CBC/PKCS5Padding";
public static final String AES_ECB_NO_PADDING = "AES/ECB/NOPadding";
public static final String AES_CBC_NO_PADDING = "AES/CBC/NOPadding";
public static byte[] encrypt(String key, byte[] value, String padding) {
try {
Key spec = generateKey(key);
Cipher cipher = buildCipher(padding);
cipher.init(Cipher.ENCRYPT_MODE, spec);
return cipher.doFinal(value);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static byte[] encrypt(String key, String vector, byte[] value, String padding) {
try {
Key spec = generateKey(key);
AlgorithmParameters iv = generateIV(vector);
Cipher cipher = buildCipher(padding);
cipher.init(Cipher.ENCRYPT_MODE, spec, iv);
return cipher.doFinal(value);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
private static Cipher buildCipher(String padding) throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException {
Cipher cipher;
if (padding.endsWith("PKCS7Padding")) {
cipher = Cipher.getInstance(padding, BouncyCastleProvider.PROVIDER_NAME);
} else {
cipher = Cipher.getInstance(padding);
}
return cipher;
}
private static Key generateKey(byte[] key) {
initialize();
return new SecretKeySpec(key, "AES");
}
private static Key generateKey(String key) {
return generateKey(key.getBytes(StandardCharsets.UTF_8));
}
private static AlgorithmParameters generateIV(byte[] vector) {
try {
initialize();
AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
params.init(new IvParameterSpec(vector));
return params;
} catch (InvalidParameterSpecException | NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
private static AlgorithmParameters generateIV(String vector) {
return generateIV(vector.getBytes(StandardCharsets.UTF_8));
}
public static byte[] decrypt(String key, byte[] encrypted, String padding) {
try {
Key spec = generateKey(key);
Cipher cipher = buildCipher(padding);
cipher.init(Cipher.DECRYPT_MODE, spec);
return cipher.doFinal(encrypted);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static byte[] decrypt(byte[] key, byte[] vector, byte[] encrypted, String padding) {
try {
AlgorithmParameters iv = generateIV(vector);
Key spec = generateKey(key);
Cipher cipher = buildCipher(padding);
cipher.init(Cipher.DECRYPT_MODE, spec, iv);
return cipher.doFinal(encrypted);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static byte[] decrypt(String key, String vector, byte[] encrypted, String padding) {
return decrypt(key.getBytes(StandardCharsets.UTF_8),
vector.getBytes(StandardCharsets.UTF_8),
encrypted,
padding);
}
public static String buildKey16() {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 4; i++) {
String[] split = UUID.randomUUID().toString().split("-");
builder.append(split[i], 0, 4);
}
return builder.toString();
}
public static String buildKey() {
try {
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(128);
//要生成多少位,只需要修改这里即可128, 192或256
SecretKey sk = kg.generateKey();
byte[] b = sk.getEncoded();
return ByteUtil.bytes2Hex(b);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
private static void initialize() {
if (initialized) {
return;
}
Security.addProvider(new BouncyCastleProvider());
initialized = true;
}
}
另外为了支持“AES/ECB/PKCS7Padding”,需要替换这两个包
local_policy.jar
US_export_policy.jar
替换这两个文件的方法比较简单,根据自己的JAVA_HOME找到对应的路径,比如我的就是
java/jre/lib/security