解密示例
示例
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;
}
}
最后修改时间: 2 年前