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

3

我想从一张德国医疗保险卡(如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();
    }

1
你已经能够获取ATR,这让我认为你认为自己接近目标。不幸的是,情况并非如此。获取您感兴趣的一代eGK规范(除ISO 7816-4之外),并检查数据存储位置(EF.Personendaten)。这是一项繁重的工作,其中包含的细节不太可能在这里现成找到。问题不在于C#,而是智能卡哲学中的命令序列。 - guidot
我已经发现,我想要的数据存储在EF.PD(或EF.PSD)中 - 问题是我不知道如何读取这个存储。 - Manuel Weitzel
文献推荐是Rankl/Effing: Handbuch der Chipkarten和ISO 7816第4部分,特别是有关SELECT、READ BINARY的章节。之后,欢迎您带着具体问题回来。 - guidot
好的,非常感谢。我已经阅读了很多关于这方面的内容,但我不明白如何构建sendBuffer以从卡中获取EF.PD并将其放入readBuffer中。我使用以下方式: byte[] buffer3 = new byte[1]; buffer3[0] = 0x00; byte[] sendBuffer = buffer3; byte[] responseBuffer = new byte[0x256]; int length = responseBuffer.Length; card.Transmit(sendBuffer, sendBuffer.Length, responseBuffer, ref length); 但我什么也没得到(只有一个数字和其他都是零)... - Manuel Weitzel
1个回答

1
粗略的顺序如下(略去了扩展长度和访问权限):
- 选择适当的DF - 选择文件EF.PD - 发送一系列“读取二进制”命令,其中增加的偏移量由P1/P2编码
以下方括号表示可选部分。
发送缓冲区必须包含命令APDU,即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”,我阅读了ISO 7816-4 pdf并发现了很多关于CLA和0x00的内容,似乎最好的选择是(“该命令是链的最后一个或唯一的命令”)。INS我选择了B0来进行ReadBinary。参数字节我设置为0x00 - 这是错误的吗?lc和le我也设置为0x00....我的错误在哪里? - Manuel Weitzel
卡片响应 67 00 -> 长度错误(十进制基数非常不寻常,因为ISO仅使用十六进制)。这是正确的,因为指定LC=0且没有数据是非法的,请参见我的可选括号。 - guidot
好的,现在(当我设置LC=0x01时)我会得到6A 86 = P1-P2参数不正确... 我设置了P1=0xD0; P2=0x01; 因为在Gematik发放的EGK规范中我找到D0 01是EF.PD文件的标识符 - 但现在出了什么问题呢? :-( - Manuel Weitzel
@ManuelWeitzel:我不知道你在说哪个命令。我不知道有任何一个命令,在其中文件标识符是在P1/P2中指定的。显然需要更多阅读ISO 7816-4。 - guidot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接