2016-09-28 10 views
0

에스토니아 ID 카드의 개인 파일을 읽으려고합니다. 그러나, 에스토니아 ID 카드에 연결할 때 WinSCard SCARD_E_PROTO_MISMATCH

00 A4 00 0C   # We choose root folder 
00 A4 01 0C 02 EE EE # We choose folder EEEE 
00 A4 02 04 02 50 44 # We choose file 5044, which contains personal data 
00 B2 XX 04   # We read record XX (see table) from the personal data file 
        # The card responds 61 YY, where YY denotes the number of bytes waiting to be read 
00 C0 00 00 YY  # We read YY bytes from the card 
        # Card responds ... 90 00, where ... is the requested data and 90 00 means status OK 

:

나는 개인 파일의 레코드 (즉, ID 번호, 이름 등)를 읽기 위해 ( here에서) 카드에 다음 데이터를 보낼 필요 원시 바이트는 T = 0 프로토콜에 있고 카드는 T = 0을 승인하기 전에 부당하게 오랜 시간 동안 T = 1에 고착됩니다.

  1. 카드 SCardStatusChange에서 독자에게
  2. 프로그램 수익을 부착하고 카드 (SCardConnect 또는 SCardReconnect) SCARD_E_SHARING_VIOLATION가 수신 오류에 연결을 시도에 카드
  3. 에게 처리 시작 다음과 같이 이벤트의 순서는 이상 약 5 초
  4. 그런 다음 연결하려고하면 SCARD_E_PROTO_MISMATCH 오류가 3 ~ 30 초 사이에 수신됩니다.
  5. 그런 다음 카드가 성공적으로 연결되고 데이터를 읽습니다.

T = 0 프로토콜에서 어떻게 든 더 빨리 연결할 수 있습니까? 다음과 같이

내 소스 코드의 단순화 된 버전입니다 : 당신 만 T0 프로토콜에 대한 독점 액세스를 위해 SCardConnect()을 요구하고있다

// NOTE: this is approximately what I do. 
// I haven't tested this code yet - it's almost 1 AM here. 
#include <winscard.h> 
void readSmartCard() { 
    LONG sCardErrorCode; 
    SCARDCONTEXT sCardContext; 
    DWORD sCardReaderStrLen = 1024; 
    wchar_t sCardReaderStr[1024]; 
    SCARDHANDLE sCardHandle; 
    DWORD sCardActiveProtocol; 
    SCARD_READERSTATE readerState; 

    sCardErrorCode = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &sCardContext); 

    // error handling macro 

    ZeroMemory(&sCardReaderState, sizeof(sCardReaderState)); 
    sCardReaderState.szReader = L"\\\\?PnP?\\Notification"; 
    sCardReaderState.pvUserData = nullptr; 
    sCardReaderState.dwEventState = SCARD_STATE_PRESENT; 

    sCardErrorCode = SCardGetStatusChange(sCardContext, INFINITE, &readerState, 1); 

    // e.h.m 

    if (readerState.dwCurrentState == 65538) { 
     sCardErrorCode = SCardListReaders(sCardContext, NULL, sCardReaderStr, &sCardReaderStrLen); 
     // e.h.m 
     readerState.szReader = sCardReaderStr; 
    } 

    sCardErrorCode = SCardGetStatusChange(sCardContext, INFINITE, &readerState, 1); 
    // e.h.m 

    if (sCardReaderState.dwEventState & SCARD_STATE_PRESENT) { 

     while (true) { 
      sCardErrorCode = SCardConnect(sCardContext, readerState.szReader, SCARD_SHARE_EXCLUSIVE, 
       SCARD_PROTOCOL_T0, &sCardHandle, &sCardActiveProtocol); 

      // e.h.m 
      printf("%x", sCardErrorCode); 
      // this will print: 
      // 8010000b (for around 5s) 
      // 8010000f (for around 20s) 
      if (sCardErrorCode == SCARD_S_SUCCESS) { 
       break; 
      } 
      Sleep(1000); 
     } 

     // open personal file and read data, yay! 
    } 
} 
+0

1) 연결을 위해 사용 된 프로토콜은 성능에서 눈에 띄는 차이를 만들어서는 안됩니다. 2) T = 0과 T = 1을 지원하는 카드는 매우 특이합니다. 3) 의심스러운 경우 항상 T = 1을 사용합니다. 적용하기 쉽고 안전한 메시징과 관련하여 더욱 강력합니다. – guidot

답변

0

인터넷을 오랫동안 수색 한 후에 명령을 변경할 필요가 없음을 발견했습니다.

전송 된 읽기/열기 명령 끝에 추가로 0 바이트를 추가하고 읽기 명령의 응답으로 데이터를 수신하기 만하면됩니다. 바이트를 수신하기 위해 별도의 명령을 사용하지 않아도됩니다.

나는 또한 모든 조건 SCARD_PCI_T1를 사용하고 SCardConnect() 기능을 할 SCARD_PCI_T0의 언급 변경할 필요 (T = 1 단지 데이터로 응답하는 동안 T = 0,는 "요청 데이터/데이터 읽기"모델을 사용하는 것 같다) T1도 허용하십시오.

여기에 괜찮은 코드 샘플을 게시 할 예정입니다.

0

를, 그래서 카드가 다음 사용중인 경우 SCARD_E_SHARING_VIOLATION이 경우 반환되며, 카드가 사용 중이 아니지만 T1이 활성화 된 경우 대신 SCARD_E_PROTO_MISMATCH이 반환됩니다.

SCardGetStatusChange()이 알림을보고하면 SCARD_STATE_INUSE과 같이 무시하는 다른 플래그도 표시 될 수 있으며 SCARD_STATE_PRESENT 플래그 만 확인합니다.

독자에게 독점 액세스가 필요한 경우 SCARD_STATE_INUSE이 지워질 때까지 기다려야하거나 SCARD_E_SHARING_VIOLATION이 더 이상보고되지 않을 때까지 기다려야합니다. 배타적 모드 대신 공유 모드로 연결할 수 있도록 로직을 변경하지 않는 한 그것에 대해 할 수있는 방법은 없습니다.

당신은 그들을 함께 OR 처리에 의해, 동시에 모두T0T1 프로토콜을 적용 SCardConnect()을 요청할 수 있습니다 (빨리 독점적 인 액세스하여 등) 현재의 프로토콜에 관계없이 독자에 연결하려면 dwPreferredProtocol 매개 변수 (예 : documentation의 예 참조). 그런 다음 매개 변수에서 T1이 활성 프로토콜로 출력되는 경우 카드를 읽기 전에 T0 프로토콜의 상태 변경을 기다릴 수 있습니다.

+0

답장을 보내 주셔서 감사합니다. 카드가 이미 사용 된 경우를 개선 할 것입니다. 그러나 T = 1에서 필요한 작업 (폴더로 이동, 개인 데이터 파일 열기, 레코드 읽기)을 수행하는 방법을 알지 못하기 때문에 프로토콜 지원을 방해합니다. T = 0에서 카드를 열 수없는 경우 T = 1을 조사하고 내가 필요한 것을 할 수 있는지 알아 봅니다. (독점적 인 액세스는이 경우에도 쓸모가 없지만 마감일에 도달하려고 했으므로 공유와 관련된 모든 문제를 피하고자했습니다.) – boxmein