feat: 获取加密激活码
This commit is contained in:
168
app/src/main/java/com/xwad/os/utils/CryptoUtils.java
Normal file
168
app/src/main/java/com/xwad/os/utils/CryptoUtils.java
Normal file
@@ -0,0 +1,168 @@
|
||||
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. 初始化Cipher(ECB无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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user