使用nfcpy读取非接触式信用卡公开信息的技术求助
非接触式信用卡公开信息读取问题(基于nfcpy库)
问题背景
我尝试用Python的nfcpy库读取自己非接触式信用卡的公开信息(姓名、有效期、卡号PAN、卡类型),目前仅能完成PPSE初始化并获取卡类型(如Visa Debit),无法进一步读取其他信息。
现有代码
import nfc try: clf = nfc.ContactlessFrontend() assert clf.open('tty:USB0:pn532') is True tag = clf.connect(rdwr={'on-connect': lambda tag:False}) cla = 0x00 # 指令类别字节 ins = 0xA4 # 指令字节:SELECT命令 p1 = 0x04 # 参数1:选择DF名称 p2 = 0x00 # 参数2:返回FCI lc = 0x00 # 数据域长度(实际可由data自动推导) data = bytearray.fromhex('325041592E5359532E4444463031') # PPSE的AID:2PAY.SYS.DDF01 le = 0x00 # 期望响应长度:返回所有可用数据 resp = tag.send_apdu(cla,ins,p1,p2,data,check_status=False) print(resp) clf.close() except Exception as EX: print(f'ERROR - {EX}') clf.close()
当前执行结果
代码返回带\x90\x00的bytearray(表示命令执行成功),响应中直接显示了"Visa Debit"卡类型,而非纯字节形式:
bytearray(b'o:\x84\x0e2PAY.SYS.DDF01\xa5(\xbf\x0c%a#O\x07\xa0\x00\x00\x00\x03\x10\x10P\nVisa Debit\x87\x01\x03\x9f\n\x08\x00\x01\x05\x01\x00\x00\x00\x00\x90\x00')
错误尝试
我找到Visa Debit的AID后,尝试发送以下APDU命令:
00 B2 01 02 A0 00 00 00 03 10 10 02
但仅得到错误响应:
bytearray(b'n\x00')
编辑说明
在Python中生成SFI文件定位符时,无需转换为二进制字符串,直接对字节做位运算即可(原代码存在索引错误,修正后如下):
sfi = 10 # 目标SFI编号 # 计算p2参数:SFI左移3位,加上记录控制位(4表示读取当前记录) sfi_recs = (sfi << 3) | 4
解决建议
1. 解析PPSE响应格式
你收到的响应是BER-TLV格式,其中"Visa Debit"是卡品牌的可读文本字段,属于正常现象。从TLV结构中可提取Visa的AID:响应中的\xa0\x00\x00\x00\x03\x10\x10就是Visa的AID(长度为7字节)。
2. 修正APDU执行流程
你发送的00 B2 01 02 ...命令错误,B2是READ RECORD命令,不需要把AID放在数据域。正确流程如下:
步骤1:选择Visa的AID
发送SELECT命令激活Visa应用:
# 选择Visa AID的APDU参数 cla = 0x00 ins = 0xA4 p1 = 0x04 p2 = 0x00 data = bytearray.fromhex('A0000000031010') # Visa的AID le = 0x00 resp = tag.send_apdu(cla, ins, p1, p2, data, check_status=False) print(resp) # 成功的话末尾会有\x90\x00
步骤2:读取信用卡记录
选择成功后,发送READ RECORD命令读取公开信息。比如读取SFI 1的记录1(存储基本卡信息):
# READ RECORD命令参数 cla = 0x00 ins = 0xB2 p1 = 0x01 # 记录编号1 p2 = 0x0C # SFI=1(左移3位得8) + 记录控制位4 = 12(0xC) le = 0x00 resp = tag.send_apdu(cla, ins, p1, p2, le=le, check_status=False) print(resp)
3. 解析读取到的记录
读取到的记录依然是BER-TLV格式,对应常用标签:
0x5A:卡号(PAN)0x5F20:持卡人姓名0x5F24:有效期(格式为YYMM)0x9F07:卡类型标识
你可以手动解析TLV,或者使用第三方库(如ber_tlv)简化解析。
4. 关于nfcpy库的适用性
nfcpy完全适合这个场景,它支持ISO-7816标准的APDU命令交互,足以完成非接触式信用卡公开信息的读取,不需要更换其他库。
内容的提问来源于stack exchange,提问作者Jonathan Fyfe
相关产品推荐
相关产品推荐

