Get the IBAN number from an emv card

依然范特西╮ 提交于 2019-12-04 13:38:34

Okay so the card has sent back this:

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

So now you've selected the application you'll want to send a series of 'Read Record' commands to it to get the data out of it like (Card number, expiry date, card holder name, IBAN (if it's in there, haven't seen it before)). The structure of the 'Read Record' command can be found in EMV Book 3 however here's some rough psuedocode as to what your Read Record loop should look like. Off the top of my head I usually set NUM_SFIS to 5 and NUM_RECORDS to 16 as there's not usually anything past these points.

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

i solved my problem after a long time this way: At first send a command to the card, to select the aid (application identifier):

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

then i hat to raise the security-level:

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

last thing to do was to read the record:

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

regards Andreas

I would like to add, the IBAN returning from the card is not straightforward.

The IBAN returned is that of the main Bank, and then the account number from the card holder in other record. Therefore one must come out with the right IBAN through code as the check digit has to be calculated as seen here

Since in records we find Country Code (DE), Bankleitzahl BLZ (8 Digits) and Account Number (10 digits), Check Digit can be calculated through

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

Source (In German): here

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!