package com.malk.rjk.util; import com.google.common.base.CharMatcher; import com.google.common.io.BaseEncoding; import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.util.Arrays; public class CryptUtil { protected byte[] aesKey; public CryptUtil(String encodingAesKey) { this.aesKey = BaseEncoding.base64().decode(CharMatcher.whitespace().removeFrom(encodingAesKey)); } public String decrypt(String encryptedText) { byte[] original; try { // 设置解密模式为AES的CBC模式 Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); SecretKeySpec keySpec = new SecretKeySpec(this.aesKey, "AES"); IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(this.aesKey, 0, 16)); cipher.init(Cipher.DECRYPT_MODE, keySpec, iv); // 使用BASE64对密文进行解码 byte[] encrypted = Base64.decodeBase64(encryptedText); // 解密 original = cipher.doFinal(encrypted); } catch (Exception e) { return null; } String trueContent; try { // 去除补位字符 byte[] bytes = decode(original); // 分离16位随机字符串,网络字节序 byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20); int contentLength = bytesNetworkOrder2Number(networkOrder); trueContent = new String(Arrays.copyOfRange(bytes, 20, 20 + contentLength), StandardCharsets.UTF_8); } catch (Exception e) { return null; } return trueContent; } public static byte[] decode(byte[] decrypted) { int pad = decrypted[decrypted.length - 1]; if (pad < 1 || pad > 32) { pad = 0; } return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad); } /** * 4个字节的网络字节序bytes数组还原成一个数字. */ private static int bytesNetworkOrder2Number(byte[] bytesInNetworkOrder) { int sourceNumber = 0; for (int i = 0; i < 4; i++) { sourceNumber <<= 8; sourceNumber |= bytesInNetworkOrder[i] & 0xff; } return sourceNumber; } }