创建时间: 2025-08-18 08:40:53
更新时间: 2025-08-18 08:55:39
您需要在gradle/maven添加本依赖
<dependencies>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20231013</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.16.0</version>
</dependency>
</dependencies>
package org.example;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.*;
import java.util.regex.*;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.json.JSONObject;
public class SecureClient {
private static final String BASE_URL = "http://lifey.icu";
private static final int BLOCK_SIZE = 16;
private static final int SESSION_TIMEOUT = 100;
private String sessionId;
private String sessionKey;
private long expireTime;
private final String secret;
private final String appId;
private String token;
private byte[] sessionHmac;
private byte[] saltSessionId;
private byte[] saltSessionKey;
private byte[] saltToken;
public SecureClient(String appId, String secret) {
this.appId = appId;
this.secret = secret;
}
private String getDeviceFingerprint() {
List<String> deviceInfoParts = new ArrayList<>();
// 基础系统信息
String osName = System.getProperty("os.name");
String osVersion = System.getProperty("os.version");
String osArch = System.getProperty("os.arch");
String osVersionDetail = System.getProperty("os.version");
deviceInfoParts.add(osName + "-" + osVersion + "-" + osArch + "-" + osVersionDetail);
// 获取CPU信息 - 尝试多种方法
String cpuInfo = getCpuInfo();
if (cpuInfo == null) {
return "hwid失败 请联系管理员";
}
deviceInfoParts.add("cpu:" + cpuInfo);
// 获取MAC地址 - 尝试多种方法
String macAddr = getMacAddress();
if (macAddr == null) {
return "hwid失败 请联系管理员";
}
deviceInfoParts.add("mac:" + macAddr);
// 添加磁盘信息作为补充标识
String diskInfo = getDiskInfo();
if (diskInfo != null) {
deviceInfoParts.add("disk:" + diskInfo);
} else {
deviceInfoParts.add("disk:unknown");
}
// 添加主板信息作为补充标识(Windows)
if (osName.toLowerCase().contains("win")) {
String boardInfo = getMotherboardInfo();
if (boardInfo != null) {
deviceInfoParts.add("board:" + boardInfo);
} else {
deviceInfoParts.add("board:unknown");
}
}
// 组合所有信息并生成哈希
String deviceString = String.join("-", deviceInfoParts);
return sha256(deviceString);
}
private String getCpuInfo() {
String osName = System.getProperty("os.name").toLowerCase();
try {
if (osName.contains("win")) {
// 尝试wmic获取CPU信息
try {
Process process = Runtime.getRuntime().exec("wmic cpu get ProcessorId,Name");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
List<String> lines = new ArrayList<>();
while ((line = reader.readLine()) != null) {
if (!line.trim().isEmpty()) {
lines.add(line.trim());
}
}
reader.close();
if (lines.size() > 1) {
return md5(lines.get(1));
}
} catch (Exception e) {
// 尝试其他方法
}
// Windows注册表获取CPU信息
try {
Process process = Runtime.getRuntime().exec(
"reg query \"HKLM\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\" /v ProcessorNameString");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
if (line.contains("ProcessorNameString")) {
String[] parts = line.split("\\s+", 3);
if (parts.length >= 3) {
return md5(parts[2]);
}
}
}
reader.close();
} catch (Exception e) {
// 尝试其他方法
}
} else if (osName.contains("linux")) {
// Linux系统从/proc/cpuinfo获取
try (BufferedReader reader = new BufferedReader(new FileReader("/proc/cpuinfo"))) {
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith("model name") || line.startsWith("cpu family")) {
return md5(line.trim());
}
}
} catch (Exception e) {
// 尝试其他方法
}
} else if (osName.contains("mac")) {
// macOS系统
try {
Process process = Runtime.getRuntime().exec("sysctl -n machdep.cpu.brand_string");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = reader.readLine();
reader.close();
if (line != null && !line.trim().isEmpty()) {
return md5(line.trim());
}
} catch (Exception e) {
// 尝试其他方法
}
}
} catch (Exception e) {
// 忽略异常
}
// 所有方法都失败时返回null
return null;
}
private String getMacAddress() {
try {
// 遍历所有网络接口获取MAC地址
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface ni = interfaces.nextElement();
// 跳过回环接口和未启动的接口
if (ni.isLoopback() || !ni.isUp()) {
continue;
}
byte[] mac = ni.getHardwareAddress();
if (mac != null && mac.length > 0) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < mac.length; i++) {
sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
}
String macAddr = sb.toString();
// 排除虚拟MAC地址
if (!macAddr.startsWith("00-00-00") && !macAddr.startsWith("FF-FF-FF")) {
return macAddr;
}
}
}
// 如果以上方法失败,尝试通过命令获取
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains("win")) {
Process process = Runtime.getRuntime().exec("ipconfig /all");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
if (line.toLowerCase().contains("物理地址") || line.toLowerCase().contains("mac address")) {
String[] parts = line.split(":");
if (parts.length > 1) {
String mac = parts[1].trim().toUpperCase();
if (!mac.isEmpty() && !mac.startsWith("00-00-00")) {
return mac;
}
}
}
}
reader.close();
} else if (osName.contains("linux") || osName.contains("mac")) {
Process process = Runtime.getRuntime().exec("ifconfig");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
if (line.toLowerCase().contains("ether") || line.toLowerCase().contains("hwaddr")) {
String[] parts = line.trim().split("\\s+");
if (parts.length > 1) {
String mac = parts[1].toUpperCase().replace(":", "-");
if (!mac.startsWith("00-00-00")) {
return mac;
}
}
}
}
reader.close();
}
} catch (Exception e) {
// 忽略异常
}
// 所有方法都失败时返回null
return null;
}
private String getDiskInfo() {
String osName = System.getProperty("os.name").toLowerCase();
try {
if (osName.contains("win")) {
// Windows获取磁盘信息
Process process = Runtime.getRuntime().exec("wmic diskdrive get SerialNumber");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
List<String> lines = new ArrayList<>();
while ((line = reader.readLine()) != null) {
if (!line.trim().isEmpty() && !line.trim().equalsIgnoreCase("SerialNumber")) {
lines.add(line.trim());
}
}
reader.close();
if (!lines.isEmpty()) {
return md5(lines.get(0));
}
} else if (osName.contains("linux")) {
// Linux获取磁盘信息
try (BufferedReader reader = new BufferedReader(new FileReader("/proc/diskstats"))) {
String line = reader.readLine();
if (line != null && !line.trim().isEmpty()) {
return md5(line.trim());
}
}
} else if (osName.contains("mac")) {
// macOS获取磁盘信息
Process process = Runtime.getRuntime().exec("diskutil info / | grep \"Volume UUID\"");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = reader.readLine();
reader.close();
if (line != null && !line.trim().isEmpty()) {
return md5(line.trim());
}
}
} catch (Exception e) {
// 忽略异常
}
return null;
}
private String getMotherboardInfo() {
try {
// 仅Windows系统获取主板信息
Process process = Runtime.getRuntime().exec("wmic baseboard get SerialNumber");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
List<String> lines = new ArrayList<>();
while ((line = reader.readLine()) != null) {
if (!line.trim().isEmpty() && !line.trim().equalsIgnoreCase("SerialNumber")) {
lines.add(line.trim());
}
}
reader.close();
if (!lines.isEmpty()) {
return md5(lines.get(0));
}
} catch (Exception e) {
// 忽略异常
}
return null;
}
private String cipher(String data, String key, boolean encrypt) throws Exception {
byte[] keyBytes;
if (key == null) {
keyBytes = Base64.decodeBase64(secret);
} else {
keyBytes = key.getBytes(StandardCharsets.UTF_8);
}
if (keyBytes.length < 32) {
keyBytes = Arrays.copyOf(keyBytes, 32);
} else {
keyBytes = Arrays.copyOf(keyBytes, 32);
}
SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");
if (encrypt) {
byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);
byte[] ivBytes = new byte[BLOCK_SIZE];
SecureRandom random = new SecureRandom();
random.nextBytes(ivBytes);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(ivBytes));
byte[] encrypted = cipher.doFinal(dataBytes);
byte[] combined = new byte[ivBytes.length + encrypted.length];
System.arraycopy(ivBytes, 0, combined, 0, ivBytes.length);
System.arraycopy(encrypted, 0, combined, ivBytes.length, encrypted.length);
return Base64.encodeBase64String(combined);
} else {
byte[] combined = Base64.decodeBase64(data);
byte[] ivBytes = Arrays.copyOfRange(combined, 0, BLOCK_SIZE);
byte[] encrypted = Arrays.copyOfRange(combined, BLOCK_SIZE, combined.length);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(ivBytes));
byte[] decrypted = cipher.doFinal(encrypted);
return new String(decrypted, StandardCharsets.UTF_8);
}
}
private JSONObject buildSecureRequest(String path, JSONObject payload) throws Exception {
payload.put("timestamp", System.currentTimeMillis());
payload.put("nonce", UUID.randomUUID().toString());
String encrypted = cipher(payload.toString(), null, true);
JSONObject request = new JSONObject();
request.put("encrypted_data", encrypted);
request.put("appid", appId);
request.put("encryption_key", secret);
return request;
}
private JSONObject sendSecureRequest(String path, JSONObject payload) {
try {
JSONObject request = buildSecureRequest(path, payload);
URL url = new URL(BASE_URL + path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
try (OutputStream os = conn.getOutputStream()) {
byte[] input = request.toString().getBytes(StandardCharsets.UTF_8);
os.write(input, 0, input.length);
}
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
try (BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
StringBuilder response = new StringBuilder();
String responseLine;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
JSONObject jsonResponse = new JSONObject(response.toString());
if (jsonResponse.has("encrypted_response")) {
String decrypted = cipher(
jsonResponse.getString("encrypted_response"),
null,
false
);
return new JSONObject(decrypted);
}
}
}
} catch (Exception e) {
System.out.println("请求错误: " + e.getMessage());
}
return null;
}
private boolean checkDebugger() {
String osName = System.getProperty("os.name").toLowerCase();
try {
if (osName.contains("win")) {
// Windows 调试检测
Process process = Runtime.getRuntime().exec("tasklist");
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
if (line.toLowerCase().contains("ollydbg") ||
line.toLowerCase().contains("ida") ||
line.toLowerCase().contains("ghidra") ||
line.toLowerCase().contains("x64dbg") ||
line.toLowerCase().contains("windbg")) {
return true;
}
}
} else if (osName.contains("linux")) {
// Linux 调试检测
File statusFile = new File("/proc/self/status");
if (statusFile.exists()) {
try (Scanner scanner = new Scanner(statusFile)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.startsWith("TracerPid:")) {
String pid = line.split("\\s+")[1];
if (!pid.equals("0")) {
return true;
}
}
}
}
}
Process process = Runtime.getRuntime().exec("ps aux");
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
if (line.toLowerCase().contains("gdb") ||
line.toLowerCase().contains("lldb") ||
line.toLowerCase().contains("strace") ||
line.toLowerCase().contains("ida")) {
return true;
}
}
}
} catch (Exception e) {
// 忽略异常
}
return false;
}
private byte[] obfuscateData(String data) {
if (data == null) return null;
SecureRandom random = new SecureRandom();
byte[] salt = new byte[16];
random.nextBytes(salt);
try {
Mac hmac = Mac.getInstance("HmacSHA256");
hmac.init(new SecretKeySpec(salt, "HmacSHA256"));
return hmac.doFinal(data.getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
return null;
}
}
private byte[] createSessionHmac() {
if (sessionId == null || sessionKey == null) return null;
String data = sessionId + sessionKey + expireTime;
try {
Mac hmac = Mac.getInstance("HmacSHA256");
hmac.init(new SecretKeySpec(
Base64.decodeBase64(secret), "HmacSHA256"));
return hmac.doFinal(data.getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
return null;
}
}
private boolean verifySessionHmac() {
if (sessionHmac == null) return false;
byte[] currentHmac = createSessionHmac();
return Arrays.equals(sessionHmac, currentHmac);
}
public boolean login(String user, String pwd) {
if (checkDebugger()) {
System.out.println("安全警告:检测到调试环境");
return false;
}
// 获取设备指纹
String deviceFingerprint = getDeviceFingerprint();
// 检查是否获取失败
if (deviceFingerprint.equals("hwid失败 请联系管理员")) {
System.out.println(deviceFingerprint);
return false;
}
System.out.println("设备指纹: " + deviceFingerprint);
JSONObject payload = new JSONObject();
payload.put("action", "login");
payload.put("username", user);
payload.put("password", pwd);
payload.put("device_id", deviceFingerprint);
payload.put("appid", appId);
JSONObject res = sendSecureRequest("/api/user/encrypted-login", payload);
if (res != null && res.optBoolean("success", false)) {
sessionId = res.optString("session_id", null);
sessionKey = res.optString("session_key", null);
token = res.optString("encrypted_token", null);
expireTime = res.optLong("expire_time", 0);
if (sessionId == null || sessionKey == null || token == null) {
return false;
}
sessionHmac = createSessionHmac();
long startTime = System.nanoTime();
performSensitiveOperation();
long duration = (System.nanoTime() - startTime) / 1_000_000;
if (duration > 500) {
clearSession();
return false;
}
return true;
}
return false;
}
private void performSensitiveOperation() {
for (int i = 0; i < 100; i++) {
SecureRandom random = new SecureRandom();
byte[] randomBytes = new byte[16];
random.nextBytes(randomBytes);
sha256Bytes(randomBytes);
}
}
private void clearSession() {
sessionId = null;
sessionKey = null;
expireTime = 0;
token = null;
sessionHmac = null;
saltSessionId = null;
saltSessionKey = null;
saltToken = null;
}
public String getSessionInfo() {
if (!verifySessionHmac()) {
return "会话无效或已被篡改";
}
try {
return "{\"session_id\": \"" + sessionId + "\", " +
"\"expire_time\": \"" + new Date(expireTime) + "\"}";
} catch (Exception e) {
return "会话数据错误: " + e.getMessage();
}
}
private static String sha256(String input) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8));
return Hex.encodeHexString(hash);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
private static String md5(String input) {
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8));
return Hex.encodeHexString(hash).substring(0, 16);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
private static byte[] sha256Bytes(byte[] input) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
return digest.digest(input);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
SecureClient client = new SecureClient(
"您的appid",
"您的加密密钥"
);
Scanner scanner = new Scanner(System.in);
System.out.print("请输入用户名: ");
String username = scanner.nextLine();
System.out.print("请输入密码: ");
String password = scanner.nextLine();
if (client.login(username, password)) {
System.out.println("登录成功");
String sessionInfo = client.getSessionInfo();
System.out.println(sessionInfo);
} else {
System.out.println("登录失败");
}
scanner.close();
}
}