You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

执行两次PACE认证会引发错误吗?JMRTD库eID读取异常求助

解决JMRTD库连续调用doPace()出现0x6986错误的方案

这个错误是电子身份证(eID)的安全机制导致的:卡片执行PACE协议后会启动会话冷却/锁定机制,短时间内重复发起PACE握手会被拒绝(SW=0x6986),即使断开读卡器连接,卡片的会话状态也不会自动重置,必须等待冷却期结束或主动触发重置。以下是具体解决办法:

1. 主动重置卡片会话,终止锁定

每次完成数据读取后,必须主动调用重置命令,而不是仅断开读卡器连接。通过以下步骤确保卡片会话被重置:

  • 调用PassportService的close()方法释放资源
  • 调用Card对象的disconnect(true)方法,注意参数必须为true,该参数会向卡片发送重置指令,直接解除会话锁定

示例代码:

PassportService passportService = null;
Card card = null;
try {
    // 初始化读卡器、卡片、PassportService逻辑
    passportService.doPace(...);
    // 执行数据读取操作
} finally {
    // 释放PassportService资源
    if (passportService != null) {
        try {
            passportService.close();
        } catch (IOException e) {
            // 处理异常
        }
    }
    // 重置卡片,解除会话锁定
    if (card != null) {
        try {
            card.disconnect(true);
        } catch (CardException e) {
            // 处理异常
        }
    }
}

2. 复用已建立的PACE会话

如果业务需要连续操作卡片,不要重复调用doPace()。第一次doPace()成功后,保持PassportService实例的有效性,后续直接使用该实例读取数据即可,无需重新执行PACE握手。

3. 测试场景下的延迟重试逻辑

如果是测试场景必须重复发起PACE握手,可以捕获CardException并检查错误码,当遇到0x6986时,添加延迟重试机制,延迟时间建议设置为65秒以上(略长于卡片默认的1分钟冷却期)。

示例代码:

int maxRetries = 3;
long delayMillis = 65000; // 65秒延迟
boolean success = false;

while (maxRetries > 0 && !success) {
    try {
        passportService.doPace(...);
        success = true;
    } catch (CardException e) {
        if (e.getMessage().contains("0x6986") && maxRetries > 1) {
            try {
                Thread.sleep(delayMillis);
            } catch (InterruptedException ie) {
                Thread.currentThread().interrupt();
                throw new RuntimeException("重试被中断", ie);
            }
            maxRetries--;
        } else {
            throw e;
        }
    }
}

内容的提问来源于stack exchange,提问作者Desperado

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 17:37:36