从 emv 卡中获取 IBAN 号码

Posted

技术标签:

【中文标题】从 emv 卡中获取 IBAN 号码【英文标题】:Get the IBAN number from an emv card 【发布时间】:2013-08-14 18:55:01 【问题描述】:

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

应用程序在 Java 7 上运行,我使用 java.smartcardio api 协议是 T=1

我的命令Apdu 获取日期如下所示:

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 吗?

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

【问题讨论】:

【参考方案1】:

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

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

所以现在您已经选择了要向其发送一系列“读取记录”命令以从中获取数据的应用程序,例如(卡号、到期日、持卡人姓名、IBAN(如果它是在那里,以前没见过))。 “读取记录”命令的结构可以在EMV Book 3 中找到,但是这里有一些关于您的读取记录循环应该是什么样子的粗略伪代码。在我的脑海中,我通常将 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);
    

【讨论】:

@andreas 我想你忘了说完你的句子? :) 或者,如果您的意思是我的回答帮助/解决了您的问题,您应该通过按左侧的勾号和/或向上箭头来接受/投票。【参考方案2】:

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

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 ;

问候 安德烈亚斯

【讨论】:

他们有持卡人的名字吗?我似乎在它的任何地方都找不到它 嗨马里奥,不,我没有找到所有者的姓名。我猜这是保存在卡的磁性存储区,而不是芯片上。【参考方案3】:

我想补充一下,从卡返回的 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

【讨论】:

以上是关于从 emv 卡中获取 IBAN 号码的主要内容,如果未能解决你的问题,请参考以下文章

避免从字符串中提取 IBAN 号码

swift code如何查询?

如何使用 Apache IBANCheckDigit 检查 IBAN 号码?

如何在四个字符组中编辑 IBAN 号码?

使用 Python 从文本中提取 IBAN

正则表达式从 IBAN 捕获 BBAN?