技术文档

Java 对接卡密验证

签名校验 + 心跳机制,完整客户端实现

本文档提供 Java 语言调用卡密验证接口的完整实现,包含 MD5 签名生成、响应验签、时间戳防重放以及心跳参数 heart=1 的使用示例。

完整实现代码

以下 KamiClient 类封装了卡密验证的核心逻辑,使用原生 java.netjava.security,无需第三方依赖,可直接集成到您的 Java 项目中。

// Java 卡密验证客户端(Java 8+)
import java.io.*;
import java.net.*;
import java.security.*;
import java.util.concurrent.*;

public class KamiClient {
    private final String baseUrl;
    private final String app;
    private final String signKey;

    public KamiClient(String userName, String app, String signKey) {
        this.baseUrl = "https://www.keyt.cn/kami/" + userName + "/check.php";
        this.app = app;
        this.signKey = signKey;
    }

    private String md5(String data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] digest = md.digest(data.getBytes());
        StringBuilder sb = new StringBuilder();
        for (byte b : digest) sb.append(String.format("%02x", b));
        return sb.toString();
    }

    private String verifyResponse(String raw) throws Exception {
        if (!raw.contains("|sign=")) return null;
        String[] parts = raw.split("\\|sign=");
        String body = parts[0];
        String sign = parts[1];

        String localSign = md5(body + signKey);
        if (!localSign.equals(sign)) return null;

        int lastPipe = body.lastIndexOf('|');
        if (lastPipe == -1) return null;
        String tsStr = body.substring(lastPipe + 1);
        long ts = Long.parseLong(tsStr);
        long nowTs = System.currentTimeMillis() / 1000;
        if (Math.abs(nowTs - ts) > 120) return null;

        return body.substring(0, lastPipe);
    }

    public String verifyCard(String card, String mac) throws Exception {
        long ts = System.currentTimeMillis() / 1000;
        String url = baseUrl + "?card=" + card + "&mac=" + mac + "&app=" + app + "&heart=1&t=" + ts;
        
        HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
        BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String raw = br.readLine();
        return verifyResponse(raw);
    }
}

核心功能说明

  • MD5 签名md5(body + signKey) 确保响应未被篡改。
  • 时间戳防重放:校验返回内容中的时间戳,与本地 UTC 时间差值不超过 120 秒。
  • 心跳支持:请求 URL 中包含 heart=1 参数,用于保持会话活跃(具体逻辑依后端配置)。
  • 纯原生实现:仅使用标准库,无第三方依赖,适合 Android 或服务端环境。

提示: 使用前请将 userNameappsignKey 替换为后台分配的实际值。完整对接流程请参考 文档首页