如何在 C# 中从智能卡中读取名称和地址等基本数据?

Posted

技术标签:

【中文标题】如何在 C# 中从智能卡中读取名称和地址等基本数据?【英文标题】:How to read fundamental data like name & address from a smartcard in c#? 【发布时间】:2015-07-21 09:55:42 【问题描述】:

我想从德国保险健康卡 (egK) 中读取姓名、地址等基本数据。 我有一个 scm sdi011 读卡器,我使用 c#。 我已经从卡/读卡器获得了 ATR 字符串,但我不知道如何继续。 如果有人能告诉我现在该做什么就好了。

这是我的代码:

    WinSCard card = new WinSCard();
    try 
       card.EstablishContext();
       card.ListReaders();
       string szReader = card.ReaderNames[1];
       card.Connect(szReader);
       string ATRStr = card.AtrString;
       ATRBox.Text = ATRStr;
     catch (WinSCardException exception) 
       richTextBox1.Text = exception.WinSCardFunctionName + " Error 0x" + exception.Status.ToString("X08") + ": " + exception.Message;
     finally 
       card.Disconnect();
    

【问题讨论】:

已经能够获得 ATR 让我觉得,您认为自己接近目标。不幸的是,这种情况并非如此。获取您感兴趣的一代的 eGK 规范(除了 ISO 7816-4),并检查数据的存储位置(EF.Personendaten)。这是很多工作,重要的细节不太可能在这里找到现成的。问题不在于 C#,而是具有特殊智能卡原理的一般命令序列。 我已经发现,我想要的数据存储在 EF.PD(或 EF.PSD)中——问题是我不知道如何读出这个存储。 文献推荐是 Rankl/Effing: Handbuch der Chipkarten 和 ISO 7816,第 4 部分,尤其是有关 SELECT、READ BINARY 的部分。之后,欢迎您带着具体问题回来。 好的,非常感谢。我现在读了很多关于这些东西的内容,但我没有得到的是如何构建 sendBuffer 以将 EF.PD 从 Card 中返回到 readBuffer 中。我像下面这样使用它: byte[] buffer3 = new byte[1];缓冲区3[0] = 0x00;字节 [] 发送缓冲区 = 缓冲区 3;字节[] responseBuffer = 新字节[0x256]; int 长度 = responseBuffer.Length; card.Transmit(sendBuffer, sendBuffer.Length, responseBuffer, 参考长度);但我什么也没得到(只有一个数字,其余的都是零)...... 【参考方案1】:

大致顺序如下(我省略了扩展长度和访问权限):

选择合适的 DF 选择文件 EF.PD 发送一系列读取二进制命令,在 P1/P2 中编码的偏移量增加

以下方括号中表示可选部分。

发送缓冲区必须包含命令 APDU,即。 e. CLA、INS、P1、P2、[LC、数据]、[LE] 最简单的方法是指定 LE=0,从那时起,卡片会尽可能多地发送,并且您知道 P1/P2 增加哪个值。

答案包含 [data] SW1/SW2,因此至少应返回两个字节。如果你得到的更少,这可能表明你的命令格式错误并被 winscard 直接拒绝,而没有发送到卡。

【讨论】:

再次嗨,我现在有 CLA=0x00; INS=0xB0; INS = 0x00; P1 = 0x00; P2 = 0x00; LC = 0x00; LE = 0x00;和 SendBuffer = CLA、INS、P1、P2、LC、LE;但我得到的唯一“数据”是这个东西“103 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0”我阅读了 ISO 7816-4 pdf 并发现了很多关于 CLA 的内容,而 0x00 似乎是最好的选择(“命令是链中的最后一个或唯一一个命令” )。 INS 我将 B0 用于 ReadBinary。我设置的参数字节 0x00 - 错了吗? lc 和 le 我也设置了 0x00.... 我的错误是什么? 卡响应 67 00 -> 长度错误(十进制基数非常不寻常,因为 ISO 仅使用十六进制)。这是正确的,因为指定 LC=0 并且没有数据是非法的,请参阅我的可选括号。 现在好了(当我做 LC=0x01 时)我得到 6A 86 = 参数不正确 P1-P2... P1=0xD0; P2=0x01;我设置了这个 P1 和 P2 因为在 gematik 的 egk 规范中我发现 D0 01 是 EF.PD 的文件标识符 - 但现在有什么问题? :-( @ManuelWeitzel:我不知道你在说哪个命令。我不知道 any 命令,其中文件标识符在 P1/P2 中指定。显然需要更多地阅读 ISO 7816-4。

以上是关于如何在 C# 中从智能卡中读取名称和地址等基本数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中从包含 XML 的字符串中读取数据?

如何在单个项目中从 C# 中的多个配置文件中读取值?

如何在 C# 中从位图中读取文本? [关闭]

如何在 PIG 脚本中从数据包中读取数据

如何在 C# 中从 XmlNode 读取属性值?

如何在 C# 中从外部站点的 url 读取 PDF 文件 [关闭]