从emv卡获取IBAN号码

时间:2013-08-13 08:37:07

标签: emv iban

我从德国CashCards (也称为Geldkarte)阅读 IBAN 号码时遇到一些问题。 我可以与我的卡通信,我从中得到一些信息。但我不知道我必须向卡片发送哪个commandApdu,以获得IBAN号码......

应用程序在Java 7上运行,我使用java.smartcardio api 协议1是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 

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

如果我原谅了一些需要的信息,我很抱歉,但这是我在这个委员会的第一个问题: - )

3 个答案:

答案 0 :(得分:0)

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

6F328407A0000000043060A52750074D61657374726F8701039F38099F33029F35019F40015F2D046465656EBF0C059F4D02190A

Which translates to

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

所以现在你已经选择了你想要发送一系列'Read Record'命令的应用程序来获取它的数据(卡号,有效期,持卡人姓名,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});
    }
}

答案 1 :(得分:0)

经过这么长时间我解决了我的问题: 首先向卡发送命令,以选择辅助(应用程序标识符):

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 };

问候 安德烈亚斯

答案 2 :(得分:0)

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

返回的IBAN是主银行的IBAN,然后是持卡人在其他记录中的帐号。因此,必须通过代码提出正确的IBAN,因为必须按照here

计算校验位。

由于我们在记录中找到国家代码(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;
    }

来源(德语):here