Проблема аутентификации MIFARE DESFire EV1

Я пытался пройти аутентификацию с помощью карты MIFARE DESFire EV1 с ключом по умолчанию (00000000h) в течение последней недели, но безрезультатно. Я следовал инструкциям этого блога, чтобы письмо. Я реализовал Send mode CBC и Receive mode CBC следующим образом:

var
  SendVector, ReceiveVector: UInt64;

procedure ResetVectors;
begin
  SendVector := 0;
  ReceiveVector := 0;
end;

procedure Encrypt(var Data: TBytes; Key: TBytes);
var
  iData, iKey: UInt64;
  i: Integer;
begin
  if Length(Data) mod 8 > 0 then
    SetLength(Data, Length(Data) + (8 - Length(Data) mod 8));

  Move(Key[0], iKey, 8);
  for i := 0 to (Length(Data) - 1) div 8 do
  begin
    Move(Data[i * 8], iData, 8);
    EncryptInt64(iData, iKey);
    Move(iData, Data[i * 8], 8);
  end;
end;

procedure EncryptInt64(var Data, Key: Int64);
begin
  Data := Data xor SendVector;
  DESEncrypt(@Data, @Key);
  SendVector := Data;
end;

procedure Decrypt(var Data: TBytes; Key: TBytes);
var
  iData, iKey: UInt64;
  i: Integer;
begin
  Move(Key[0], iKey, 8);
  for i := 0 to (Length(Data) - 1) div 8 do
  begin
    Move(Data[i * 8], iData, 8);
    DecryptInt64(iData, iKey);
    Move(iData, Data[i * 8], 8);
  end;
end;

procedure DecryptInt64(var Data, Key: Int64);
var
  Tmp: UInt64;
begin
  Tmp := ReceiveVector;
  ReceiveVector := Data;
  DESDecrypt(@Data, @Key);
  Data := Data xor Tmp;
end;

Это журнал команд APDU, которые я отправил на карту, и их соответствующие ответы:

-->90 6A 00 00 00 // List Applications
<--01 02 03 
<--9100 (OK)

-->90 5A 00 00 03 00 00 00 00 // Select PICC
<--9100 (OK)

-->90 1A 00 00 01 00 00 // ISO Authenticate with master key (00000000h)
<--91AF

-->90 AF 00 00 00 // Retreive RndB
<--A4 4C 2B D1 EB 6F 64 0C 
<--9100 (OK)

-->90 AF 00 00 10 0D 9F 27 9B A5 D8 72 60 25 DD 7A 19 63 0F 26 2D 00 // Send DES(RndA + RndB')
<--91AE (AUTHENTICATION_FAILURE)

Вот весь код моего метода Authenticate:

procedure Authenticate;
var
  Key, Data: TBytes;
  s: string;
  b: Byte;
  RndA: UInt64;
  i: Integer;
begin
  ResetVectors;
  Key := HexStringToBuffer('00 00 00 00 00 00 00 00');
  s := '90 1A 00 00 01 00 00';
  s := SendAPDU(s, False);
  Data := HexStringToBuffer(s);
  Decrypt(Data, Key);

  b := Data[0];
  for i := 0 to 6 do
    Data[i] := Data[i + 1];
  Data[7] := b;

  RndA := 1; // not very wise

  SetLength(Data, 16);
  Move(Data[0], Data[8], 8);
  Move(RndA, Data[0], 8);

  Encrypt(Data, Key);
  s := '90 AF 00 00 10 ' + BufferToHexString(Data) + ' 00';
  SendAPDU(s, False);
end;

Я не понимаю, почему карта категорически отвергает мою попытку аутентификации. есть идеи?


Вот схема алгоритмов CBC Send и CBC Receive в соответствии с инструкциями производителя DESFire EV1: CBC SendПолучение CBC


person iMan Biglari    schedule 06.01.2014    source источник
comment
В статье, на которую вы ссылаетесь, нет такого кода. У вас есть рабочий код? Например, некоторый пример кода C. Длина (данные) мод 8 выглядит странно. Уверены ли вы? И вызовы FillChar могут быть просто := 0.   -  person David Heffernan    schedule 06.01.2014
comment
@DavidHeffernan Вы правы насчет вызовов SetLength() и FillChar. Я изменил свой код, чтобы исправить его, но у меня все еще есть проблема. К сожалению, я нигде не могу найти рабочий код... Только фрагменты кода тут и там. Вот ссылка на один из них: stackoverflow.com/questions/11385963/   -  person iMan Biglari    schedule 06.01.2014
comment
Может быть, это сообщение полезно? Иман, какую библиотеку шифрования DES вы используете?   -  person whosrdaddy    schedule 06.01.2014
comment
@whosrdaddy Я использую библиотеку, которую уже довольно давно использую с контактными смарт-картами ACOS3X. И я перевел код в этом посте на Паскаль, но получил ту же ошибку :-(   -  person iMan Biglari    schedule 06.01.2014


Ответы (2)


Попробуйте заменить шифрование на расшифровку в шифре DES. Карта ВСЕГДА использует режим DES ENCRYPT (как при получении, так и при отправке данных). И хост ВСЕГДА использует режим DECRYPT.

Для получения дополнительной информации: https://ridrix.wordpress.com/2009/09/19/mifare-desfire-communication-example/#comment-30

person Jirka Grigar    schedule 28.02.2015
comment
Этот ответ НЕВЕРНЫЙ. То, что вы пишете, было правильно для старых карт Desfire с устаревшей проверкой подлинности. Но Desfire EV1 в режиме ISO или AES смешивает режим шифрования во время аутентификации. - person Elmue; 11.07.2016
comment
Да, моя ошибка, спасибо за разъяснение. Я написал старую версию аутентификации. - person Jirka Grigar; 14.07.2016

Во время аутентификации ISO или AES используется следующая схема:

  1. Случайное B получено с карты с помощью RECEIVE + DECIPHER
  2. Случайный АБ отправляется на карту с помощью SEND + ENCIPHER
  3. Случайный A получен с помощью RECEIVE + DECIPHER

ВАЖНО: ВСЕ шифрование проходит через CBC. IV ключа, используемого для шифрования/дешифрования CBC, сбрасывается только ОДИН РАЗ в начале. Затем его необходимо поддерживать в актуальном состоянии во время ВСЕХ следующих команд.

Если вы используете режим ISO или AES, после успешной аутентификации вы ДОЛЖНЫ также вычислить CMAC для отправленных команд и полученных данных, иначе ваш IV не будет синхронизирован с картой, и вы будете получать ошибку целостности каждый раз, когда используете сеансовый ключ. !

Поскольку я боролся с теми же проблемами, я опубликовал несколько примеров общения, которые очень помогут вам в тестировании вашего кода. Вы найдете их здесь, в Stackoverflow: Примеры связи Desfire EV1 Там же вы найдете ссылку на мой источник код, который я рекомендую вам изучить.

person Elmue    schedule 11.07.2016