3

我在从德国 CashCards(也称为 Geldkarte)读取IBAN号码时遇到了一些问题。我可以与我的卡进行通信,并从中获取一些信息。但我不知道我必须向卡发送哪个命令Apdu,才能获得 IBAN 号码......

该应用程序在 Java 7 上运行,我使用java.smartcardio api Protocoll is T=1

我的 commandApdu 获取日期如下所示:

byte[] commandBytes = new byte[]{0x00, (byte)0xa4, 0x04, 0x00, 0x07, (byte)0xa0, 0x00, 0x00, 0x00,0x04, 0x30, 0x60, 0x00};

我得到的信息是:

6F 32 84 07 A0 00 00 00 04 30 60 A5 27 50 07 4D 61 65 73 74 72 6F 87 01 03 9F 38 09 9F 33 02 9F 35 01 9F 40 01 5F 2D 04 64 65 65 6E BF 0C 05 9F 4D 02 19 0A 

谁能告诉我获取 IBAN 号码的正确 apdu 吗?

如果我忘记了一些需要的信息,我很抱歉,但这是我在这个板上的第一个问题 :-)

4

3 回答 3

1

很长一段时间后,我以这种方式解决了我的问题:首先向卡发送命令,以选择帮助(应用程序标识符):

private static byte[] aidWithPossibleIban = new byte[] { 0x00, (byte) 0xa4,
            0x04, 0x00, 0x09, (byte) 0xa0, 0x00, 0x00, 0x00, 0x59, 0x45, 0x43,
            0x01, 0x00, 0x00 };

然后我想提高安全级别:

private static byte[] cmdRaiseSecurityLevel = new byte[] { 0x00, 0x22,
            (byte) 0xf3, 0x02 };

最后要做的是阅读记录:

private static byte[] readSelectedRecord = new byte[] { 0x00, (byte) 0xb2,
            0x01, (byte) 0xa4, 0x00 };

问候安德烈亚斯

于 2013-10-02T08:25:49.580 回答
1

好的,所以卡已经发回了这个:

6F328407A0000000043060A52750074D61657374726F8701039F38099F33029F35019F40015F2D046465656EBF0C059F4D02190A

翻译为

6F File Control Information (FCI) Template
    84 Dedicated File (DF) Name
        A0000000043060
    A5 File Control Information (FCI) Proprietary Template
        50 Application Label
            M a e s t r o
        87 Application Priority Indicator
            03
        9F38 Processing Options Data Object List (PDOL)
            9F33029F35019F4001
        5F2D Language Preference
            d e e n
        BF0C File Control Information (FCI) Issuer Discretionary Data
            9F4D Log Entry
                190A

因此,现在您已经选择了要向其发送一系列“读取记录”命令以从中获取数据的应用程序(卡号、到期日期、持卡人姓名、IBAN(如果在其中,以前没见过))。'Read Record' 命令的结构可以在EMV Book 3中找到,但是这里有一些关于你的 Read Record 循环应该是什么样子的粗略伪代码。在我的脑海中,我通常将 NUM_SFIS 设置为 5,将 NUM_RECORDS 设置为 16,因为通常没有超过这些点。

for (int sfiNum = 1; sfiNum <= NUM_SFIS; sfiNum++) 
{ 
    for (int rec = 1; rec <= NUM_RECORDS; rec++) 
    {
          byte[] response = tag.transceive(new byte[]{0x00,(byte)0xB2 (byte)rec, (byte)((byte)(sfiNum << 3) | 4), 0x00});
    }
}
于 2013-09-19T23:08:17.967 回答
1

我想补充一下,从卡返回的 IBAN 并不简单。

返回的IBAN是主银行的,然后是其他记录中持卡人的帐号。因此,必须通过代码得出正确的 IBAN,因为必须按照此处所示计算校验位

由于在记录中我们找到国家代码 (DE)、Bankleitzahl BLZ(8 位数字)和帐号(10 位数字),因此可以通过以下方式计算校验位

 public string ReturnIBAN(string lkz, string blz, string kntnr, bool groupedReturn = true)
    {
        string bban = string.Empty;

        lkz = lkz.ToUpper();
        switch (lkz)
        {
            case "AT":
                {
                    bban = blz.PadLeft(5, '0') + kntnr.PadLeft(11, '0');
                }
                break;
            case "DE":
                {
                    bban = blz.PadLeft(8, '0') + kntnr.PadLeft(10, '0');
                }
                break;
            case "CH":
                {
                    bban = blz.PadLeft(5, '0') + kntnr.PadLeft(12, '0');
                }
                break;
        }
        string sum = bban + lkz.Aggregate("", (current, c) => current + (c - 55).ToString()) + "00";

        var d = decimal.Parse(sum);
        var checksum = 98 - (d % 97);
        string iban = lkz + checksum.ToString().PadLeft(2, '0') + bban;
        return groupedReturn ? iban.Select((c, i) => (i % 4 == 3) ? c + " " : c + "").Aggregate("", (current, c) => current + c) : iban;
    }

资料来源(德语):这里

于 2016-01-20T08:54:57.030 回答