Smartcard 讀寫器函數庫的使用說明

 
一、IC卡與作業系統的整合
前面所談的標準及各種IC卡的規格,多半只論及IC卡或讀卡機。使用者要使用讀卡機時,必須安裝廠商提供之驅動程式(drivers),開發應用程式。
PC/SC(Personal Computer/Smart Card)支援ISO7816-4的基本指令集,界定了IC卡、讀卡機及作業系統的責任與分工,各家讀卡機廠商只要遵循PC/SC所定義之介面與方法開發驅動程式,即可結合到Windows或其他作業系統,應用程式只要透過單一標準介面與作業系統溝通,就可輕易操控各種讀卡機讀寫IC卡。
Microsoft也在1997年底提供了Smart Card SDK給應用程式開發者,陸陸續續許多廠商的IC卡、讀卡機產品開始宣稱其產品符合PC/SC規範,PC/SC儼然成為未來時勢的潮流。
應用程式與Smartcard之運作如下:
1、應用程式使用PC/SC API 傳送APDU指令傳給作業系統。
2、作業系統透過符合PC/SC規範之驅動程式將APDU指令傳給讀卡機。
3、讀卡機使用T=0或T=1之通訊協議將指令傳送至Smartcard傳輸管理器。
4、傳輸管理器再將APDU指令傳送至Smartcard COS運作後回覆處理結果。

二、PC/SC API for Visual C++
1、#i nclude <winscard.h>
winscard.h是Visual C++編譯時所需要的參數及基本資料結構,請記得連結時加入winscard.lib,這樣才能完成您的程式,此兩檔在Visual C++ 的 include及library目錄下可以找到,這種方式稱為「隱式調用DLL」,程式好像與winscard.dll無關但實際上是透過DLL執行,.h檔案內容大致如下:

#define SCARD_STATE_UNAWARE 0x00000000
#define SCARD_STATE_IGNORE 0x00000001
#define SCARD_STATE_CHANGED 0x00000002
#define SCARD_STATE_UNKNOWN 0x00000004
#define SCARD_STATE_UNAVAILABLE 0x00000008

WINSCARDDATA extern const SCARD_IO_REQUEST
g_rgSCardT0Pci,
g_rgSCardT1Pci,
g_rgSCardRawPci;

extern WINSCARDAPI LONG WINAPI
SCardEstablishContext(
IN DWORD dwScope,
IN LPCVOID pvReserved1,
IN LPCVOID pvReserved2,
OUT LPSCARDCONTEXT phContext);

其實 PC/SC 不一定要在Windows 系統執行,以下定義為Linux系統所使用之PC/SC,請比較一下差異在哪裡。

typedef struct {
DWORD dwProtocol; /* SCARD_PROTOCOL_T0 or SCARD_PROTOCOL_T1 */
DWORD cbPciLength; /* Length of this structure - not used */
} SCARD_IO_REQUEST;

long SCardEstablishContext(unsigned long dwScope,const void *pvReserved1, const void *pvReserved2, long *phContext);

以下說明一些重要函式之功能,細節部分請參考,附件二、PC/SC API Reference Document。

2、ScardEstablishContext
SCardEstablishContext 直覺的解釋就是建立PC/SC在作業系統下的資源,所有PC/SC應用程式開始時一定要呼叫此函式建立資源後才能開始運作,範例如下。

SCARDCONTEXT hContext;
LONG rv;
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);

3、ScardListReaders
SCardListReaders 直覺的解釋就是列出此台機器可用之Smartcard 讀卡機,比較特別的是第一次呼叫時並不知道機器有幾台可用之讀卡機所以mszReaders先代入NULL,取得實際數量後再呼叫一次就可列出讀卡機名稱,此技巧運用在很多API 呼叫中,第一次看到覺得怪怪,仔細想想此種呼叫方式真聰明。

LPTSTR mszReaders;
DWORD dwReaders;
rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
mszReaders = (LPTSTR)malloc(sizeof(char)*dwReaders);
rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);

4、ScardConnect
SCardConnect 直覺的解釋就是建立Smartcard之連線,參數就是代入SCardListReaders 所列出之讀卡機名稱;當連線完成後Smartcard會被重置,傳回ATR訊息。

SCARDHANDLE hCard;
DWORD dwActiveProtocol;
rv = SCardConnect(hContext, "Reader X", SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0, &hCard, &dwActiveProtocol);

5、ScardBeginTransaction
當讀卡機以分享方式開啟時,SCardBeginTransaction 就是宣告爾後將執行一連串的APDU指令以確保中間不被插斷,當結束所有APDU指令後需呼叫ScardEndTransaction讓其他連線繼續運作;當讀卡機以獨占方式開啟時,可以不必執行此函式,直接執行SCardTransmit即可。

rv = SCardBeginTransaction(hCard);

6、ScardTransmit
SCardTransmit是在呼叫SCardConnect函式後,傳送APDU 指令到Smartcard的函式,可說是整個Smartcard程式設計的核心,在此特別說明下列程式。
DWORD dwSendLength, dwRecvLength;
SCARD_IO_REQUEST pioRecvPci;
/*必須使用BYTE傳送及接收資料,如果您輸入的指令是CHAR記得轉換為BYTE ,很特別的是此函式呼叫時就已經定義好接收資料*/
BYTE pbRecvBuffer[10];
/*此行即為APDU Command,特別解釋一下,這行指令是選取Master File。
Command CLA INS P1 P2 Lc Data Le
Select C0 A4 00 00 02 3F00
*/
BYTE pbSendBuffer[] = { 0xC0, 0xA4, 0x00, 0x00, 0x02, 0x3F, 0x00 };

dwSendLength = sizeof(pbSendBuffer);
dwRecvLength = sizeof(pbRecvBuffer);
rv = SCardTransmit(hCard, SCARD_PCI_T0, pbSendBuffer, dwSendLength,
&pioRecvPci, pbRecvBuffer, &dwRecvLength);

7、SCardEndTransaction
SCardEndTransaction 是結束之前SCardBeginTransaction 之宣告;必須與SCardBeginTransaction配對使用。

rv = SCardEndTransaction(hCard, SCARD_LEAVE_CARD);

8、ScardDisconnect
SCardDisconnect 是結束之前SCardConnect所建立的連線,呼叫此函式後就無法在傳送APDU指令了。

rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);

9、ScardReleaseContext
SCardReleaseContext 直覺的解釋就是釋放SCardEstablishContext 在作業系統下所建立的資源,所有PC/SC應用程式結束時一定要呼叫此函式歸還資源。

rv = SCardReleaseContext(hContext);

10、其他PC/SC API
PC/SC API函式不只這些,某些應用場合可能會使用到,請參考附件二、PC/SC API Reference Document。

三、PC/SC API for Visual Basic
API可說是系統的一部份,請搜尋winscard.dll您會發現它位於system32目錄下,這個檔包含PC/SC所有的函式,所以PC/SC API函式VB的定義會變成這樣:

Global Const SCARD_CLASS_VENDOR_INFO = 1 ' Vendor information definitions
Global Const SCARD_CLASS_COMMUNICATIONS = 2 ' Communication definitions
Global Const SCARD_CLASS_PROTOCOL = 3 ' Protocol definitions
Global Const SCARD_CLASS_POWER_MGMT = 4 ' Power Management definitions
Global Const SCARD_CLASS_SECURITY = 5 ' Security Assurance definitions
Global Const SCARD_CLASS_MECHANICAL = 6 ' Mechanical characteristic definitions
Global Const SCARD_CLASS_VENDOR_DEFINED = 7 ' Vendor specific definitions
Global Const SCARD_CLASS_IFD_PROTOCOL = 8 ' Interface Device Protocol options

Public Type SCARD_IO_REQUEST
dwProtocol As Long
cbPciLength As Long
End Type

Public Declare Function SCardEstablishContext Lib "WinScard.dll" ( _
ByVal dwScope As Long, _
ByVal pvReserved1 As Long, _
ByVal pvReserved2 As Long, _
ByRef phContext As Long _
) As Long

從Visual Basic函式定義可以看出,PC/SC API應用程式都是呼叫winscard.dll來處理Window作業系統之資源分配、讀卡機及傳送APDU指令的功能,這種方式稱為「顯式調用DLL」。

[教學手冊] PC/SC Smartcard APDU 教學手冊
http://www.fcnet.idv.tw/~erichsiao/smartcard

你可能感兴趣的:(Smartcard 讀寫器函數庫的使用說明)