使用APDU命令访问葡公民卡PIN保护数据遇6982错误求助
葡萄牙公民卡读取受PIN保护的EF05(地址)返回6982(安全条件未满足)问题解决
问题梳理
你目前的情况是:葡萄牙公民卡的公共数据(如EF02、EF08)能正常读取,但受PIN保护的EF05(地址)在PIN验证成功后,读取时返回6982(安全条件未满足)。当前操作流程是选卡→选MF→选公共DF→选EF05→读取,但权限验证后仍无法访问。
核心问题排查与解决方案
1. 先确认PIN验证的正确性
葡萄牙公民卡的地址PIN对应PIN2(地址PIN),验证时必须使用正确的PIN参考参数:
- 正确的PIN验证APDU格式:
00 20 00 82 08 [PIN_HEX]- P2=82:指定验证地址PIN(签名PIN的P2是80,别搞混)
- PIN_HEX:需转换为8字节十六进制,不足位用
FF填充(比如PIN是1234,则为31323334FFFFFF)
如果之前验证时用了P2=80(签名PIN),哪怕验证成功,也无法获得地址数据的访问权限。
2. 调整操作流程顺序
必须先验证PIN,再选择目标EF05,部分智能卡要求权限验证后重新绑定上下文:
正确流程:
- 选卡(你的原命令正确):
00A4040007604632FF000002 - 选择MF:
00A4000C023F00 - 选择公共DF:
00A4000C025F00 - 验证地址PIN(这一步放在选EF05之前)
- 选择EF05(注意EF标识符是
05,不是EF05) - 执行读取命令
3. 修正EF选择命令的参数
你原代码中EF_VALUE如果写的是EF05,会导致选择命令变成00A4000C02EF05,这是错误的——EF的标识符是05,正确的选择命令是:00A4000C0205
修正后的代码示例
// 1. 选卡 await sendAPDUCommand(scContext, cardContext, "00A4040007604632FF000002"); // 2. 选MF await sendAPDUCommand(scContext, cardContext, "00A4000C023F00"); // 3. 选公共DF await sendAPDUCommand(scContext, cardContext, "00A4000C025F00"); // 4. 验证地址PIN(替换为你的PIN十六进制,8字节) const pinHex = "31323334FFFFFF"; // 示例:PIN为1234时的十六进制 const verifyResp = await sendAPDUCommand(scContext, cardContext, `0020008208${pinHex}`); if (verifyResp.returnCode !== "9000") { console.error("PIN验证失败:", verifyResp.returnCode); return; } // 5. 选择EF05 await sendAPDUCommand(scContext, cardContext, "00A4000C0205"); // 6. 读取EF05数据 let data = ""; const max_value = 10; // 根据EF05实际长度调整,可先读00偏移看返回结果 for (let j = 0; j <= max_value; j++) { const segment = j.toString(16).padStart(2, "0").toUpperCase(); const segmentData = await sendAPDUCommand(scContext, cardContext, `00B0${segment}0000`); if (segmentData.returnCode === "9000") { data += segmentData.value; } else if (segmentData.returnCode === "6700") { // 长度错误,说明数据已读完 break; } else { console.error("读取失败:", segmentData.returnCode); break; } } console.log("读取到的地址数据:", data);
额外检查点
- 如果仍返回
6982,可以用00A4020C00命令列出当前DF下的所有EF,确认EF05的实际标识符是否为05 - 确认PIN未被锁定:如果之前多次验证失败,卡可能锁定了地址PIN,需解锁后再尝试
内容的提问来源于stack exchange,提问作者ep-cbit
相关产品推荐
相关产品推荐

