import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Base64;
import static java.nio.charset.StandardCharsets.UTF_8;
public class CryptoUtils {
private static AesCrypto textCrypto = null; // key for text data
public static void init(String key) {
if (textCrypto == null) {
textCrypto = new AesCrypto(key);
}
}
public static String decryptText(final String cypherData) {
return new String(textCrypto.decryptBytes(TrimBase64.decode(cypherData)), UTF_8);
}
public static String encryptText(final String planData) {
return TrimBase64.encode(textCrypto.encryptBytes(planData.getBytes(UTF_8)));
}
private static class TrimBase64 {
private static byte[] decode(String text) {
if (text == null) {
return null;
}
// padding trailing ‘=‘
int length = text.length();
switch (length % 4) {
case 2:
text += "==";
break;
case 1:
text += "===";
break;
case 3:
text += "=";
break;
default:
break;
}
return Base64.getDecoder().decode(text);
}
private static String encode(byte[] data) {
// trim trailing ‘=‘
return data == null ? null : Base64.getEncoder().encodeToString(data).replaceAll("=*$", "");
}
}
private static class AesCrypto {
private final SecretKeySpec keySpec;
private final SecureRandom srandom;
AesCrypto(String hexKey) {
if (!testKeys(hexKey)) {
throw new RuntimeException("AES Key invalid");
}
keySpec = new SecretKeySpec(fromHex(hexKey), "AES");
srandom = new SecureRandom();
}
/**
* AES-128/192/256 allowed
*
* @param hexKey
* @return
*/
private boolean testKeys(String hexKey) {
return hexKey != null && (hexKey.length() == 32 || hexKey.length() == 48 || hexKey.length() == 64);
}
private byte[] fromHex(String hexStr) {
if (hexStr == null) {
return null;
}
int length = hexStr.length();
if (length % 2 == 1) {
return null;
}
int byteLength = length / 2;
byte[] raw = new byte[byteLength];
for (int i = 0; i < byteLength; i++) {
raw[i] = (byte) Integer.parseInt(hexStr.substring(i + i, i + i + 2), 16);
}
return raw;
}
private byte[] decryptBytes(byte[] sBytes) {
if (sBytes == null) {
return null;
}
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
int ivSize = cipher.getBlockSize();
IvParameterSpec ivSpec = new IvParameterSpec(sBytes, 0, ivSize);
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] payload = cipher.doFinal(sBytes, ivSize, sBytes.length - ivSize);
return payload;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private byte[] encryptBytes(byte[] sBytes) {
if (sBytes == null) {
return null;
}
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] iv = new byte[cipher.getBlockSize()];
srandom.nextBytes(iv);
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] payload = cipher.doFinal(sBytes);
byte[] encrypted = new byte[iv.length + payload.length];
System.arraycopy(iv, 0, encrypted, 0, iv.length);
System.arraycopy(payload, 0, encrypted, iv.length, payload.length);
return encrypted;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
}
原文:https://www.cnblogs.com/lhp2012/p/11019749.html