Получить номер IBAN с карты EMV
У меня есть некоторые проблемы с чтением номера IBAN с немецкой CashCards (также известной как Geldkarte). Я могу общаться с моей картой, и я получаю некоторую информацию от нее. но я не знаю, какую команду я должен отправить на карту, чтобы получить номер IBAN...
Приложение работает на Java 7, и я использую java.smartcardio api
Протоколл Т =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
Кто-нибудь может сказать мне правильный apdu для получения номера IBAN?
Прошу прощения, если я забыл нужную информацию, но это мой первый вопрос на этом форуме:-)
3 ответа
После долгого времени я решил свою проблему следующим образом: сначала отправьте команду на карту, чтобы выбрать помощь (идентификатор приложения):
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 };
С уважением Андреас
Итак, карта отправила обратно это:
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, однако вот несколько грубых psuedocode относительно того, как должен выглядеть ваш цикл чтения 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});
}
}
Я хотел бы добавить, что возвращение 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;
}
Источник (на немецком языке): здесь