java代码验证事例

创建时间: 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();
    }
}