2013-02-21 3 views
0

Следующий код работает и позволяет мне получить UID карты Mifare 1k. К сожалению, он не работает с картами Desfire.Mifare DESFIRE EV1 GetCardUid

public byte[] GetUid() 
    { 
     byte[] uid = new byte[6]; 
     int rc = Communicate(new byte[]{0xff, 0xca, 0x00, 0x00, 0x04}, ref uid); 
     if (rc != 0) 
      throw new Exception("failure: " + rc); 

     int rc1, rc2; 
     if (uid.Length == 2) 
     { 
      rc1 = uid[0]; 
      rc2 = uid[1]; 
     } 
     else 
     { 
      rc1 = uid[4]; 
      rc2 = uid[5]; 
     } 

     if (rc1 != 0x90 || rc2 != 0x00) 
      throw new Exception("failure: " + rc1 + "/" + rc2); 

     byte[] result = new byte[4]; 
     Array.Copy(uid, result, 4); 
     return result; 
    } 

Я имел взгляд на следующие ресурсы

... и попытался сделать это следующим образом:

 byte[] outb = new byte[15]; 
     int rc9 = Communicate(new byte[] { 0x60 }, ref outb); 

outb всегда содержит {0x67, 0x00} и нет, как ожидалось, {af 04 01 01 00 02 18 05}.

Подключиться успешно, и SCardGetAttrib позволяет мне получать ATR. Метод Communicate работает с SCardTransmit. Я могу опубликовать код, если это поможет.

Спасибо за любой указатель!

EDIT:

Спасибо за первый ответ! Я изменил программу, как было предложено:

 byte[] outb = new byte[9]; 
     int rc5 = Communicate(new byte[]{0x90, 0x60, 0x00, 0x00, 0x00, 0x00}, ref outb); 

Теперь outb is {0x91, 0x7E}. Это выглядит лучше, 0x91 выглядит как код ответа ISO 7816, но, к сожалению, не 0x90, как и ожидалось. (Я также посмотрел на макрос DESFIRE_TRANSCEIVE во второй ссылке, которая продолжает чтение, если он получает 0xf2.) Я попробовал поиск Google для кодов ответа на код ISO 7816 APDU, но не успел декодировать код ошибки.

EDIT 2:

Я также нашел следующий комментарий:

с Omnikey 5321 я получаю DESFire ATR 3B8180018080 UID 04 52 2E AA 47 23 80 90 00 [от APDU FFCA000000 ] Все другие APDU дают 917E неизвестного ошибка

Это объясняет мой код ошибки и дает мне еще один намек, FFCA000000 смотрит довольно s похожий на мою другую строку Mifare 1k. Таким образом, с FFCA000000 я получаю 9-байтовый ответ, который, похоже, содержит UID. Интересно, что код FFCA000000 также работает с картами 1k, поэтому, возможно, мое решение состоит в том, чтобы изменить последние 04:00 и обработать ответы различной длины. Правильно?

EDIT 3:

Кажется пенни упал ... 0x04 = 4 байта ответа = слишком мал для 7 байт UID = ответа 917E = буфер слишком мал :-)

ответ

1

Try «Первичная завернутая» версия первой ссылки, которую вы поставили вместо нее. Ваш интерфейс ожидает, что стиль APDU в стиле ISO 7816-4 (так как он возвращает статусное слово ISO 7816-4, означающее неправильную длину).

3

Этот код, кажется, работает:

 int rc = Communicate(new byte[] { 0xff, 0xca, 0x00, 0x00, 0x00 }, ref uid); 
     if (rc != 0) 
      throw new Exception("failure: " + rc); 

     int rc1 = uid[uid.Length-2], rc2 = uid[uid.Length-1]; 

     if (rc1 != 0x90 || rc2 != 0x00) 
      throw new Exception("failure: " + rc1 + "/" + rc2); 

     byte[] result = new byte[uid.Length - 2]; 
     Array.Copy(uid, result, uid.Length - 2); 
     return result; 

Любые комментарии?

+0

Спасибо за обмен кода с нами, рад, что я помог вам в правильном направлении. –

+0

Какое оборудование было проверено? –

+0

Mifare DESfire EV1, Mifare Classic 1k и Mifare Classic 4k. –

2

Команды cla = ff представляют собой команды pcsc part 3. Ins = ca должен работать с любым CL-считывателем, который соответствует pcsc 2.0x

Смежные вопросы