C # PCSC-sharp Отправка / получение пользовательских команд с данными - PullRequest
0 голосов
/ 01 октября 2018

Я работаю над программой C # Java Card (Smart Card) и пытаюсь использовать библиотеку PCSC-sharp на github.

Вот "short / tl; dr "версия моего запроса: Пример PCSC-sharp охватывает Iso7816 Case2Short.Может ли кто-то или исправить мои примеры ниже, или предоставить мне пример Iso7816 Case3Short (Данные команды. Нет данных ответа) и Case4Short (Данные команды. Ожидаемые данные ответа)?

Вот «длинная» версия моего запроса: На плате Java я использую как стандартные, так и пользовательские команды APDU, и я могу успешно вызывать эти команды с помощью скрипта Python (с библиотекой смарт-карт).Другими словами, я доказал работоспособность команд Java Card.

Моя цель сейчас - использовать PCSC-sharp для выполнения тех же команд, но у меня не получается, когда я включаю данные (т. Е. APDU LC> 0).

Вот пример на github.Обратите внимание, что я могу использовать это только с изменениями имени читателя, инструкции (выберите файл вместо вызова вызова) и Le.

var contextFactory = ContextFactory.Instance;
using (var ctx = contextFactory.Establish(SCardScope.System)) {
    using (var isoReader = new IsoReader(ctx, "ACME Smartcard reader", 
        SCardShareMode.Shared, SCardProtocol.Any, false)) {

        var apdu = new CommandApdu(IsoCase.Case2Short, isoReader.ActiveProtocol) {
            CLA = 0x00, // Class
            Instruction = InstructionCode.GetChallenge,
            P1 = 0x00, // Parameter 1
            P2 = 0x00, // Parameter 2
            Le = 0x08 // Expected length of the returned data
        };

        var response = isoReader.Transmit(apdu);
        Console.WriteLine("SW1 SW2 = {0:X2} {1:X2}", response.SW1, response.SW2);
        // ..
    }
}

APDU в моей версии примера переводится в:

Send: 00 A4 00 00 00 00
Resp: 90 00

... который работает для меня и подходит для Case2Short (нет данных, нет ответа)

Я пытаюсь воссоздать два разных типа переводов:

Case3Short (Данные команды. Нет данных ответа)

Send: 00 A4 04 00 06 01 02 03 04 05 06 00
Resp  90 00

Вот мой код:

    private bool SendApduCase3()
    {
        var success = false;
        DebugWriteLine("case3 start");
        using (var isoReader = new IsoReader(td.context, td.name, SCardShareMode.Shared, SCardProtocol.T1, false))
        {
            DebugWriteLine("case3 command");
            var commandApdu = new CommandApdu(IsoCase.Case3Short, isoReader.ActiveProtocol)
            {
                CLA = 0x00,
                INS = 0xA4,
                P1 = 0x04,
                P2 = 0x00,
                Data = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 },
                Le = 0x00
            };

            DebugWriteLine("case3 transmit");
            var response = isoReader.Transmit(commandApdu);
            if ((response.SW1 == 0x90) && (response.SW2 == 0x00)) success = true;
        }
        DebugWriteLine("case3 " + success.ToString());
        return (success);
    }

... но он цепляется за команду и никогдаделает это для передачи, вместо этого возвращая следующую ошибку:

System.ArgumentException:
    Iso7816-4 Case3Short does not expect any data fields in its return value and therefore has no bytes for Le
at PCSC.Iso7816.CommandApdu.set_Le(Int32 value)

, если = 0x00 удалено, то команда отправляется, но теперь она зацикливается на передаче, что странно, поскольку не должноданные не возвращаются.

ReaderPresent: catch case3
PCSC.Exceptions.InsufficientBufferException: The data buffer to receive returned data is too small for the returned data."

Case4Short (Данные команды. Ожидаемые данные ответа)

Send: 80 11 00 00 04
Resp: 01 02 03 04 90 00

Вот мой код:

    private bool SendApduCase4()
    {
        var success = false;
        DebugWriteLine("case4 start");
        using (var isoReader = new IsoReader(td.context, td.name, SCardShareMode.Shared, SCardProtocol.T1, false))
        {
            DebugWriteLine("case4 command");
            var commandApdu = new CommandApdu(IsoCase.Case3Short, isoReader.ActiveProtocol)
            {
                CLA = 0x00,
                INS = 0xA4,
                P1 = 0x00,
                P2 = 0x00,
                Data = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 },
                Le = 0x00
            };

            DebugWriteLine("case4 transmit");
            var response = isoReader.Transmit(commandApdu);
            if (response.HasData) DebugWriteLine(response.GetData().ToString());
            if ((response.SW1 == 0x90) && (response.SW2 == 0x00))
            {
                if (response.HasData)
                {
                    byte[] expected = new byte[] { 0x51, 0x01, 0x02, 0x03 };
                    if (response.GetData() == expected) success = true;
                }
            }

        }
        DebugWriteLine("case4 " + success.ToString());
        return (success);
    }

... аналогично, он ловит команду и никогда не делает это для передачи

Что яздесь делаешь неправильно?

Да, и самый близкий ответ, который я нашел в своем поиске, был здесь , но не охватывал то, что мне нужно.

1 Ответ

0 голосов
/ 03 октября 2018

Случай 3 не ожидает никаких возвращаемых данных.Если вы не ожидаете данных, то Le не должно присутствовать.Le - это кодировка ожидаемого объема данных, называемая Ne.Le = 00 означает: дайте мне максимум количество 256 байт взамен: Ne = 256.Таким образом, включение любого значения Le делает его командой ISO для случая 4.Если Le отсутствует, то Ne = 0.

Обычно смарт-карты будут отправлять правильный ответ, даже если установлен Le.К сожалению для вас, библиотека PCSC-sharp решила по-другому и запретила вам отправлять команду - что, вероятно, хорошо, поскольку реализация смарт-карты может по-прежнему возвращать ошибку.


Когда вы удалили Le = 00, вы столкнулись с другой проблемой.SELECT по имени (INS = A4 и P1 = 04 с P2 = 00 могут фактически возвращать управляющие данные файла, что делает его командой ISO для случая 4. На этот раз команда правильно составлена ​​как случай ISO 3, но карта вернула данные, для которыхв библиотеке не было зарезервировано буферное пространство - после получения ответа выдается ошибка.

Для теста 3 необходимо использовать INS = A4, P1 = 04 и P2 = 0C, что указывает на отсутствие данных ответаожидается или любая другая фактическая команда случая ISO 3, такая как SELECT по идентификатору файла, конечно.


Примечания:

  • ISO здесь является сокращением от ISO / IEC 7816-4, если фотографы могут использовать имя ISO, то и разработчики смарт-карт
...