PC/SC 函式庫簡介
PC/SC 全名是 Personal Computer/Smart Card,是一套專門為智慧卡和讀卡機之間溝通所設計的標準規範。這個規範是由 PC/SC Workgroup 制定的。
PC/SC 函式庫是根據這個規範實作的 API 集合,使我們在開發智慧卡應用程式時能夠更加方便。
本文將簡單介紹 PC/SC 函式庫的基本概念、使用流程及 APDU 通訊協定,幫助你更好地理解這個重要的智慧卡標準。
PC/SC 基本概念
PC/SC 規範定義了智慧卡與電腦之間的互動標準。它包含硬體和軟體兩個層面的規範。在軟體方面,主要的實作包括 Windows 系統的 WinSCard 和跨平台的 PCSCLite。
PC/SC 與其他智慧卡標準
在深入了解 PC/SC 函式庫的使用流程之前,我們有必要了解 PC/SC 在整個智慧卡技術生態系統中的位置。PC/SC 雖然是一個重要的標準,但它並非孤立存在的。讓我們來看看 PC/SC 與其他幾個常見的智慧卡相關標準之間的關係。
JavaCard
JavaCard 是一個在智慧卡上運行的應用開發平台。與 PC/SC 不同,JavaCard 允許開發者使用 Java 語言為智慧卡編寫應用程式。PC/SC 則專注於主機和讀卡機之間的通訊。
在實際應用中,我們常常會使用 PC/SC 來與運行 JavaCard 應用的智慧卡進行通訊。
ISO 7816
ISO 7816 是一系列關於智慧卡的國際標準,涵蓋了從物理特性到傳輸協議等多個方面。PC/SC 在很大程度上是基於 ISO 7816 標準的,特別是在 APDU 通訊協議方面。
我們可以將 PC/SC 視為 ISO 7816 標準在個人電腦環境下的具體實現。
NFC
NFC(Near Field Communication)是一種短距離無線通訊技術,常用於非接觸式智慧卡和移動支付。雖然 PC/SC 主要針對接觸式智慧卡,但它也支持某些非接觸式卡。
許多 NFC 讀卡器可以通過 PC/SC 介面與電腦通訊,這為 NFC 應用提供了更廣泛的使用場景。
PKCS#11
PKCS#11 是一個加密令牌介面標準,定義了應用程式如何使用智慧卡等加密設備。與關注底層通訊的 PC/SC 不同,PKCS#11 專注於更高層次的加密操作。
在實際應用中,許多 PKCS#11 的實現會在底層使用 PC/SC 來與智慧卡進行通訊。
總結來說,PC/SC 在智慧卡技術體系中扮演著基礎通訊的角色。它為其他更高層次的標準和技術提供了必要的通訊能力。在開發智慧卡應用時,我們往往需要將 PC/SC 與其他標準或技術結合使用,以實現更複雜、更安全的功能。
理解了 PC/SC 與其他標準的關係,我們就能更好地把握 PC/SC 在智慧卡開發中的重要性。
接下來,讓我們深入了解 PC/SC 函式庫的基本使用流程。
PC/SC 函式庫的基本使用流程
使用 PC/SC 函式庫與智慧卡進行通訊,通常遵循以下基本流程:
- 建立上下文: SCardEstablishContext()
- 列舉讀卡機: SCardListReaders()
- 連接卡片: SCardConnect()
- 執行卡片操作
- 斷開連接: SCardDisconnect()
- 釋放上下文: SCardReleaseContext()
以下是一個簡單的流程圖,展示了 PC/SC 函式庫的使用流程:
卡片操作函數
連接卡片後,可以使用以下函數進行各種操作:
- SCardTransmit(): 發送 APDU 命令
- SCardBeginTransaction() / SCardEndTransaction(): 開始/結束交易
- SCardControl(): 發送讀卡機命令(如 PIN Pad 操作)
- SCardStatus() / SCardGetAttrib() / SCardGetStatusChange(): 獲取卡片狀態
APDU 通訊協定
APDU (Application Protocol Data Unit) 是基於 ISO7816-4 標準的智慧卡通訊協定。它定義了命令 (Command) 和回應 (Response) 的格式:
Command APDU: [CLA][INS][P1][P2][Lc][Data][Le]
Response APDU: [Data][SW1][SW2]
APDU 命令格式詳解:
- CLA (1 byte): 指示命令類別
- INS (1 byte): 指示特定命令
- P1, P2 (各 1 byte): 命令參數
- Lc (0-3 bytes): 表示後續 Data 欄位的長度
- Data (變長): 命令資料
- Le (0-3 bytes): 期望的回應資料長度
APDU 回應格式詳解:
- Data (變長): 回應資料
- SW1, SW2 (各 1 byte): 狀態字,表示命令執行的結果
實際應用範例
以下是一個簡單的 C++ 範例,展示如何使用 PC/SC 函式庫連接智慧卡並讀取 ATR (Answer To Reset):1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
int main() {
SCARDCONTEXT hContext;
SCARDHANDLE hCard;
DWORD dwActiveProtocol;
BYTE pbAtr[32];
DWORD dwAtrLen = sizeof(pbAtr);
// 建立上下文
if (SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext) != SCARD_S_SUCCESS) {
std::cerr << "Failed to establish context." << std::endl;
return 1;
}
// 列出讀卡器
LPTSTR pmszReaders;
DWORD dwReaders;
if (SCardListReaders(hContext, NULL, NULL, &dwReaders) != SCARD_S_SUCCESS) {
std::cerr << "Failed to list readers." << std::endl;
SCardReleaseContext(hContext);
return 1;
}
pmszReaders = (LPTSTR) malloc(dwReaders * sizeof(char));
if (SCardListReaders(hContext, NULL, pmszReaders, &dwReaders) != SCARD_S_SUCCESS) {
std::cerr << "Failed to list readers." << std::endl;
free(pmszReaders);
SCardReleaseContext(hContext);
return 1;
}
// 連接卡片(假設使用第一個可用的讀卡器)
if (SCardConnect(hContext, pmszReaders, SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol) != SCARD_S_SUCCESS) {
std::cerr << "Failed to connect to card." << std::endl;
free(pmszReaders);
SCardReleaseContext(hContext);
return 1;
}
// 獲取 ATR
if (SCardStatus(hCard, NULL, NULL, NULL, NULL, pbAtr, &dwAtrLen) == SCARD_S_SUCCESS) {
std::cout << "ATR: ";
for (DWORD i = 0; i < dwAtrLen; i++) {
printf("%02X ", pbAtr[i]);
}
std::cout << std::endl;
} else {
std::cerr << "Failed to get card status." << std::endl;
}
// 斷開連接並釋放資源
SCardDisconnect(hCard, SCARD_LEAVE_CARD);
free(pmszReaders);
SCardReleaseContext(hContext);
return 0;
}
常見問題和注意事項
- 讀卡機驅動問題:確保已正確安裝讀卡機驅動。
- 權限問題:某些系統可能需要管理員權限才能訪問智慧卡讀卡機。
- 多執行緒安全:在多執行緒環境中使用 PC/SC 函式庫時需要特別注意同步問題。
- 錯誤處理:應該總是檢查 PC/SC 函數的返回值,以確保操作成功。
- 資源釋放:記得在使用完畢後釋放所有分配的資源,避免記憶體洩漏。
結論
PC/SC 函式庫為開發智慧卡應用提供了標準化的介面。通過理解其基本概念、使用流程以及 APDU 協定,開發者可以更有效地實現智慧卡與電腦之間的安全通訊。
參考資源
- PC/SC Workgroup 官方網站
https://pcscworkgroup.com/ - Microsoft WinSCard API 文件
https://learn.microsoft.com/zh-tw/windows/win32/api/winscard/ - PCSC-Lite 專案
https://pcsclite.apdu.fr/ - ISO/IEC 7816 標準
https://www.zeroplus.com.tw/E-paper/200908/image/200908ZEROPLUS_iso7816.pdf