使用PCSC-Sharp向MiFare 1k卡发送Select File APDU命令失败求助
问题分析与解决方案
你的问题出在错误地将Lc字节(0x0C)和额外的0x00字节包含到了Data属性中,导致生成的APDU不符合ISO 7816规范,触发InvalidApduException。
正确的APDU拆解
先明确你要发送的命令结构:
00 A4 04 0C 0C D2 76 00 01 35 4B 41 4E 4D 30 31 00 00 ├─ CLA: 0x00 ├─ INS: 0xA4 (SelectFile) ├─ P1: 0x04 ├─ P2: 0x0C ├─ Lc: 0x0C (表示后续有12字节数据) ├─ Data: 0xD2 0x76 0x00 0x01 0x35 0x4B 0x41 0x4E 0x4D 0x30 0x31 0x00 └─ Le: 0x00 (请求返回所有可用数据)
CommandApdu会自动根据Data的长度生成Lc字节,不需要你手动添加;同时最后的0x00是Le参数,不属于数据部分。
修正后的代码方案
方案1:手动修正参数
var contextFactory = ContextFactory.Instance; using (var ctx = contextFactory.Establish(SCardScope.System)) { using (var isoReader = new IsoReader(ctx, readerName, SCardShareMode.Shared, SCardProtocol.Any, false)) { var apdu = new CommandApdu(IsoCase.Case4Short, isoReader.ActiveProtocol) { CLA = 0x00, Instruction = InstructionCode.SelectFile, // 0xA4 P1 = 0x04, P2 = 0x0C, // 仅保留12字节的实际数据,去掉Lc(0x0C)和额外的0x00 Data = new byte[] { 0xD2, 0x76, 0x00, 0x01, 0x35, 0x4B, 0x41, 0x4E, 0x4D, 0x30, 0x31, 0x00 }, Le = 0x00, }; var response = isoReader.Transmit(apdu); Console.WriteLine("SW1 SW2 = {0:X2} {1:X2}", response.SW1, response.SW2); } }
方案2:直接传入完整APDU字节数组(更不易出错)
如果你不确定手动拆分参数的正确性,可以直接将完整的命令字节数组传入CommandApdu构造函数,框架会自动解析各部分:
var contextFactory = ContextFactory.Instance; using (var ctx = contextFactory.Establish(SCardScope.System)) { using (var isoReader = new IsoReader(ctx, readerName, SCardShareMode.Shared, SCardProtocol.Any, false)) { // 直接使用完整的命令字节数组 var apduBytes = new byte[] { 0x00, 0xA4, 0x04, 0x0C, 0x0C, 0xD2, 0x76, 0x00, 0x01, 0x35, 0x4B, 0x41, 0x4E, 0x4D, 0x30, 0x31, 0x00, 0x00 }; var apdu = new CommandApdu(apduBytes); var response = isoReader.Transmit(apdu); Console.WriteLine("SW1 SW2 = {0:X2} {1:X2}", response.SW1, response.SW2); } }
补充说明
IsoCase.Case4Short的选择是正确的,因为你的命令包含数据部分和Le参数,且Le使用1字节编码。- 若后续仍有问题,可以检查卡片是否支持该SELECT命令的P1/P2组合(0x04/0x0C表示按DF名称选择),以及卡片是否处于可接收命令的状态。
内容的提问来源于stack exchange,提问作者Ivan-Mark Debono
相关产品推荐
相关产品推荐

