Files
Xuewang365OSNeutral/app/src/main/java/com/xwad/os/utils/CryptoUtils.java

168 lines
6.0 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.xwad.os.utils;
import android.util.Base64;
import android.util.Log;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* Android 对称加密解密工具类
* 支持 AES/DES/TripleDES + ECB/CBC/CFB/OFB/CTR + PKCS5Padding 等
*/
public class CryptoUtils {
/**
* 简化解密方法:仅需传入待解密字符串
*
* @param data 待解密的字符串
* @return 解密后的原文
* @throws Exception 解密异常
*/
public static String decrypt(String data) {
String KEY = JgyUtils.getAesKey();
String IV = JgyUtils.getAesIv();
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// 解码密钥
byte[] keyBytes = KEY.getBytes(StandardCharsets.UTF_8);
SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");
// 初始化Cipher
// 解码偏移量IV
byte[] ivBytes = IV.getBytes(StandardCharsets.UTF_8);
AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
// 解码待解密数据
byte[] dataBytes = Base64.decode(data, Base64.DEFAULT);
// 执行解密并返回字符串
byte[] decryptBytes = cipher.doFinal(dataBytes);
return new String(decryptBytes, StandardCharsets.UTF_8);
} catch (GeneralSecurityException e) {
e.printStackTrace();
Log.e("CryptoUtils", "decrypt: " + e.getMessage());
}
return "";
}
/**
* 对称解密核心方法
*
* @param data 待解密的字符串
* @param type 加密类型AES / DES / TRIPLEDES
* @param mode 模式ECB / CBC / CFB / OFB / CTR
* @param pad 填充方式PKCS5Padding / ISO10126Padding / NoPadding
* @param key 密钥字符串
* @param keyType 密钥编码Utf8 / Base64 / Hex
* @param iv 偏移量ECB模式无需
* @param ivType 偏移量编码Utf8 / Base64 / Hex
* @param isBase64 待解密数据编码true=Base64 false=Hex
* @return 解密后的原始字符串
* @throws Exception 解密异常(密钥长度/算法不支持/数据错误等)
*/
public static String decrypt(
String data,
String type,
String mode,
String pad,
String key,
String keyType,
String iv,
String ivType,
boolean isBase64
) throws Exception {
// 1. 拼接算法全称
String algorithm = type + "/" + mode + "/" + pad;
Cipher cipher = Cipher.getInstance(algorithm);
// 2. 解码密钥(修复:== 改为 equals() 字符串值比较)
byte[] keyBytes;
if ("Hex".equals(keyType)) {
keyBytes = hex2Bytes(key);
} else if ("Base64".equals(keyType)) {
keyBytes = Base64.decode(key, Base64.DEFAULT);
} else {
// 强制指定UTF-8避免乱码
keyBytes = key.getBytes(StandardCharsets.UTF_8);
}
SecretKeySpec secretKey = new SecretKeySpec(keyBytes, type);
// 3. 初始化CipherECB无IV其他模式需要IV
if ("ECB".equals(mode)) {
cipher.init(Cipher.DECRYPT_MODE, secretKey);
} else {
// 解码偏移量IV
byte[] ivBytes;
if ("Hex".equals(ivType)) {
ivBytes = hex2Bytes(iv);
} else if ("Base64".equals(ivType)) {
ivBytes = Base64.decode(iv, Base64.DEFAULT);
} else {
ivBytes = iv.getBytes(StandardCharsets.UTF_8);
}
AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
}
// 4. 解码待解密数据
byte[] dataBytes;
if (isBase64) {
dataBytes = Base64.decode(data, Base64.DEFAULT);
} else {
dataBytes = hex2Bytes(data);
}
// 5. 执行解密 + 转字符串
byte[] decryptBytes = cipher.doFinal(dataBytes);
return new String(decryptBytes, StandardCharsets.UTF_8);
}
/**
* 全Android版本兼容的 Hex字符串 → 字节数组 解码
* 替代Apache Commons-Codec的Hex.decodeHex
*/
private static byte[] hex2Bytes(String hexStr) {
if (hexStr == null || hexStr.length() == 0) return new byte[0];
byte[] bytes = new byte[hexStr.length() / 2];
for (int i = 0; i < bytes.length; i++) {
int high = Character.digit(hexStr.charAt(2 * i), 16);
int low = Character.digit(hexStr.charAt(2 * i + 1), 16);
bytes[i] = (byte) (high << 4 | low);
}
return bytes;
}
// ------------------- 你的业务调用示例直接复制到Android Activity/ViewModel中使用 -------------------
public static void testDecrypt() {
// 你的原始配置参数(完全不变)
String data = "88072p8780";
String type = "AES";
String mode = "CBC";
String pad = "PKCS5Padding";
String key = "fRW5b5FI4uG32HISvVZ40QFSkyvXYwP8";
String keyType = "Utf8";
String iv = "7COBgH2wUtJnPPSX";
String ivType = "Utf8";
boolean isBase64 = true;
try {
// 执行解密
String result = decrypt(data, type, mode, pad, key, keyType, iv, ivType, isBase64);
// 输出结果Android中用Log.d不要用System.out
Log.d("Crypto", "解密结果:" + result);
} catch (Exception e) {
// 异常捕获(密钥错误/算法不支持/数据被篡改等)
e.printStackTrace();
Log.e("Crypto", "解密失败:" + e.getMessage());
}
}
}