Как я могу отправить команду APDU, используя C++?
Я хочу создать программное обеспечение, которое подключается к смарт-карте HID OMNIKEY 3128 "Aviator chip". Мне удалось подключить это устройство с помощью функции API "SCardConnect", но в соответствии с рекомендациями разработчика (стр. 17) https://www.hidglobal.com/doclib/files/resource_files/plt-03099_a.3_-_omnikey_sw_dev_guide.pdf Я должен изменить последовательность напряжений, чтобы решить проблему чтения / записи, и это можно сделать, отправив команду APDU: "Как я могу отправить эти команды, используя C++, Есть ли функция API, чтобы сделать это, как SCardConnect?
1 ответ
Оговорка первая: я раньше не использовал PC/SC API, но мне стало интересно, что ваш вопрос связан с проектом, который я делал давно. - Таким образом, следующее не проверено и должно быть принято с небольшим количеством соли:-)
Если я правильно понимаю страницу 26 в вашем связанном документе, функции, которые будут использоваться, являются (желательно) SCardTransmit
или же SCardControl
,
Пример того, как передать команду APDU, можно найти, например, на https://ludovicrousseau.blogspot.com/2010/04/pcsc-sample-in-c.html. Стоит прочитать приведенные там описания. Соответствующие части в основном сводятся к:
// dwActiveProtocol is result of SCardConnect
SCARD_IO_REQUEST pioSendPci = dwActiveProtocol == SCARD_PROTOCOL_T1 ? *SCARD_PCI_T1 : *SCARD_PCI_T0;
BYTE pbRecvBuffer[258];
BYTE cmd[] = { 0x00, 0xA4, 0x04, 0x00,
0x0A, 0xA0, 0x00, 0x00,
0x00, 0x62, 0x03, 0x01,
0x0C, 0x06, 0x01 }; // this is just an example, not the right command (yet, see below).
dwRecvLength = sizeof(pbRecvBuffer);
LONG rv = SCardTransmit(hCard, &pioSendPci, cmd, sizeof(cmd), NULL, pbRecvBuffer, &dwRecvLength);
Теперь вопрос в том, как сочинять cmd
, Здесь могут быть полезны примеры C# на https://github.com/hidglobal/HID-OMNIKEY-Sample-Codes. В частности, вы должны посмотреть на SetVoltageSequence() и VoltageSequence.SetApdu (). Если я правильно понимаю, что-то вокруг следующего должно работать:
BYTE constexpr voltageSequence = 0x1B; // or 0x39 or ..., see page 17 in your linked document.
BYTE cmd[] = { 0xFF, 0x70, 0x07, 0x6B,
0x0B, 0xA2, 0x09, 0xA1,
0x07, 0xA3, 0x05, 0xA0,
0x03, 0x82, 0x01, voltageSequence, 0x00};
Я предполагаю, что весь необходимый код для связи с устройством должен быть более или менее доступен в связанном коде примера C#.