智慧卡架構

本主題適用於 IT 專業人員,說明在 Windows 作業系統中支援智慧卡的系統架構,包括認證提供者架構和智慧卡子系統架構。

驗證是驗證物件或人員身分識別的程式。 當您驗證智慧卡等物件時,目標是要確認物件是否為正版。 當您驗證人員時,目標是要確認您未處理冒充。

在網路環境中,驗證是向網路應用程式或資源證明身分識別的動作。 一般而言,身分識別是由密碼編譯作業所證明,而密碼編譯作業只使用使用者知道的密鑰 (,例如使用公鑰密碼編譯) 或共用密鑰。 驗證交換的伺服器端會比較已簽署的數據與已知的密碼編譯密鑰,以驗證驗證嘗試。 將密碼編譯金鑰儲存在安全的中央位置,可讓驗證程式可調整且可維護。

針對智慧卡,Windows 支援符合安全驗證需求且可延伸的提供者架構,讓您可以包含自定義認證提供者。 本主題包含下列相關信息:

認證提供者架構

下表列出互動式登入架構中包含的元件:

元件 說明
Winlogon 提供互動式登入基礎結構。
登入UI 提供互動式UI轉譯。
認證提供者 (密碼和智慧卡) 描述認證資訊和串行化認證。
本地安全機構 (LSA) 處理登入認證。
驗證套件 包含 NTLM 和 Kerberos 通訊協定。 與伺服器驗證套件通訊以驗證使用者。

Windows 中的互動式登入會在使用者按 CTRL+ALT+DEL 時開始。 CTRL+ALT+DEL 按鍵組合稱為 SAS) (的安全注意順序。 為了防止其他程式和進程使用它,Winlogon 會在開機程式期間註冊此順序。

收到 SAS 之後,UI 會從從已註冊認證提供者收到的信息產生登入圖格。 下圖顯示 Windows 作業系統中認證提供者的架構。

認證提供者架構。

一般而言,使用本機帳戶或網域帳戶登入計算機的用戶必須輸入使用者名稱和密碼。 這些認證可用來驗證使用者的身分識別。 針對智慧卡登入,用戶的認證會包含在智慧卡的安全性晶元上。 智慧卡卡片閱讀機可讓電腦與智慧卡上的安全性晶元互動。 當使用者使用智慧卡登入時,他們會輸入個人標識碼 (PIN) ,而不是使用者名稱和密碼。

認證提供者是在本機系統上執行並用來收集認證的進程中 COM 物件。 登入UI提供互動式UI轉譯,Winlogon提供互動式登入基礎結構,而認證提供者會使用這兩個元件來協助收集和處理認證。

Winlogon 會指示登入 UI 在收到 SAS 事件之後顯示認證提供者磚。 登入UI會查詢每個認證提供者,以取得它想要列舉的認證數目。 認證提供者可以選擇將其中一個磚指定為預設值。 在所有提供者都列舉其磚之後,登入UI會向用戶顯示它們。 使用者會與磚互動,以提供適當的認證。 登入 UI 會提交這些認證以進行驗證。

與支援的硬體結合,認證提供者可以擴充 Windows 作業系統,讓用戶能夠使用生物特徵辨識 (登入,例如指紋、復寫或語音識別) 、密碼、PIN、智慧卡憑證或任何自定義驗證套件。 企業和 IT 專業人員可以為所有網域用戶開發和部署自定義驗證機制,而且可能會明確要求使用者使用此自定義登入機制。

注意

認證提供者不是強制機制。 它們可用來收集和串行化認證。 LSA 和驗證套件會強制執行安全性。

認證提供者可以設計成支援單一登錄 (SSO) 。 在此程式中,他們會使用RADIUS和其他) 來登入計算機的技術,來向安全的網路存取點 (驗證使用者。 認證提供者也設計來支援應用程式特定的認證收集,並可用於驗證網路資源、將計算機加入網域,或提供系統管理員同意用戶帳戶控制 (UAC) 。

多個認證提供者可以在計算機上共存。

認證提供者必須在執行 Windows 的電腦上註冊,並負責:

  • 描述驗證所需的認證資訊
  • 處理與外部驗證授權單位的通訊和邏輯
  • 封裝互動式和網路登入的認證

注意

認證提供者 API 不會轉譯 UI。 它會描述需要轉譯的內容。
只有密碼認證提供者可在安全模式中使用。
智慧卡認證提供者可在網路期間以安全模式使用。

智慧卡子系統架構

廠商提供智慧卡和智慧卡卡片閱讀機,而且在許多情況下,智慧卡和智慧卡卡片閱讀機的廠商都不同。 智慧卡卡片閱讀機的驅動程式會寫入 個人電腦/智慧卡 (計算機/SC) 標準。 每個智慧卡都必須有密碼編譯服務提供者 (CSP) 使用 CryptoAPI 介面來啟用密碼編譯作業,以及使用 WinSCard API 來啟用與智慧卡硬體的通訊。

基礎 CSP 和智慧卡迷你驅動程序架構

下圖顯示 CryptoAPI、CSP、智慧卡基底密碼編譯服務提供者 (基底 CSP) 和智慧卡迷你驅動程式之間的關聯性。

基礎 CSP 和智慧卡迷你驅動程序架構。

使用基底 CSP 和智慧卡 KSP 進行快取

智慧卡架構會使用快取機制來協助簡化作業,以及改善使用者對 PIN 的存取。

  • 數據快取:數據快取提供單一程式,以將智慧卡 I/O 作業最小化
  • PIN 快取:PIN 快取可協助使用者不必在每次智慧卡未經驗證時重新輸入 PIN

數據快取

每個 CSP 會個別實作目前的智慧卡數據快取。 基底 CSP 實作健全的快取機制,可讓單一程式將智慧卡 I/O 作業降至最低。

現有的全域快取運作方式如下:

  1. 應用程式要求密碼編譯作業。 例如,用戶憑證是要從智慧卡讀取
  2. CSP 會檢查其快取是否有專案
  3. 如果在快取中找不到專案,或是快取專案但不是最新狀態,則會從智慧卡讀取專案
  4. 從智慧卡讀取任何項目之後,它會新增至快取。 該專案的任何現有過期復本都會被取代

CSP 會快取三種類型的對象或數據:釘選 (以取得詳細資訊,請參閱 PIN 快 取) 、憑證和檔案。 如果任何快取的數據變更,則會在後續作業中從智慧卡讀取對應的物件。 例如,如果檔案寫入智慧卡,CSP 快取會變成檔案過期,而其他進程至少讀取智慧卡一次,以重新整理其 CSP 快取。

全域數據快取裝載於適用於 Windows 的智慧卡服務中。 Windows 包含兩個公用智慧卡 API 呼叫:SCardWriteCache 和 SCardReadCache。 這些 API 呼叫可讓應用程式使用全域數據快取功能。 每個符合智慧卡迷你驅動程式規格的智慧卡都有16位元組的卡片標識碼。 此值可用來唯一識別與指定智慧卡相關的快取數據。 使用標準 Windows GUID 類型。 這些 API 可讓應用程式將資料新增至全域快取並從中讀取數據。

PIN 快取

PIN 快取可防止使用者在每次智慧卡未經驗證時輸入 PIN。 驗證智慧卡之後,它不會區分主機端應用程式,任何應用程式都可以存取智慧卡上的私人數據。

為了減輕這種情況,智慧卡會在應用程式向智慧卡進行驗證時進入獨佔狀態。 不過,這表示其他應用程式無法與智慧卡通訊,而且將會遭到封鎖。 因此,這類獨佔聯機會最小化。 問題是 Kerberos 通訊協定) 等通訊協定 (需要多個簽署作業。 因此,通訊協定需要延長智慧卡的獨佔存取權,或需要多個驗證作業。 這是 PIN 快取用來將智慧卡的獨佔使用最小化,而不會強制使用者多次輸入 PIN。

下列範例說明其運作方式。 在此案例中,有兩個應用程式:Outlook 和 Internet Explorer。 應用程式會將智慧卡用於不同的用途。

  1. 用戶啟動 Outlook,並嘗試傳送已簽署的電子郵件。 私鑰位於智慧卡上
  2. Outlook 會提示使用者輸入智慧卡 PIN。 使用者輸入正確的 PIN 碼
  3. 電子郵件數據會傳送至智慧卡以進行簽章作業。 Outlook 用戶端會格式化回應並傳送電子郵件
  4. 用戶開啟 Internet Explorer,並嘗試存取需要傳輸層安全性 (TLS) 驗證用戶端的受保護網站
  5. Internet Explorer 會提示使用者輸入智慧卡 PIN。 使用者輸入正確的 PIN 碼
  6. TLS 相關的私鑰作業會在智慧卡上進行,而且使用者已通過驗證並登入
  7. 使用者返回 Outlook 以傳送另一封已簽署的電子郵件。 這次,系統不會提示使用者輸入 PIN,因為 PIN 是從先前的作業快取而來。 同樣地,如果使用者再次使用 Internet Explorer 進行另一項作業,Internet Explorer 將不會提示使用者輸入 PIN 碼

基底 CSP 會在內部維護 PIN 的每個進程快取。 PIN 會加密並儲存在記憶體中。 用來保護 PIN 的函式為 RtlEncryptMemory、RtlDecryptMemory 和 RtlSecureZeroMemory,這會清空包含 PIN 的緩衝區。

智慧卡選取專案

本文中的下列各節說明 Windows 如何使用智慧卡架構,為成功的智慧卡登入選取正確的智慧卡閱讀機軟體、提供者和認證:

容器規格層級

為了回應 CryptoAPI 中的 CryptAcquireContext 呼叫,基底 CSP 會嘗試比對呼叫端指定的容器與特定智慧卡和讀取器。 呼叫端可以提供具有不同規格層級的容器名稱,如下表所示,並從最特定到最不特定的要求進行排序。

同樣地,為了回應 CNG 中的 NCryptOpenKey 呼叫,智慧卡 KSP 會嘗試以相同方式比對容器,並採用相同的容器格式,如下表所示。

注意

使用智慧卡 KSP 開啟金鑰之前,必須先呼叫 NCryptOpenStorageProvider () MS_SMART_CARD_KEY_STORAGE_PROVIDER

類型 名稱 格式
讀取器名稱和容器名稱 \.<Reader Name><Container Name>
第二 NULL) (讀取器名稱和容器名稱 \.<Reader Name>
第三 僅限容器名稱 <Container Name>
IV 默認容器 (僅限 NULL)

基底 CSP 和智慧卡 KSP 快取智慧卡會處理有關呼叫進程的資訊,以及進程已存取的智慧卡相關信息。 搜尋智慧卡容器時,基底 CSP 或智慧卡 KSP 會先檢查其快取中的程式。 如果快取的句柄無效或找不到相符專案,則會呼叫SCardUIDlg API 來取得卡片句柄。

容器作業

您可以使用 CryptAcquireContext 來要求下列三個容器作業:

  1. 建立新的容器。 (將 dwFlags 設定為 CRYPT_NEWKEYSET 之 CryptAcquireContext 的 CNG 對等專案為 NCryptCreatePersistedKey.)
  2. 開啟現有的容器。 (CryptAcquireContext 開啟容器的 CNG 對等專案為 NCryptOpenKey.)
  3. 刪除容器。 (將 dwFlags 設定為 CRYPT_DELETEKEYSET 之 CryptAcquireContext 的 CNG 對等專案為 NCryptDeleteKey.)

用來將密碼編譯句柄與特定智慧卡和讀取器建立關聯的啟發學習法,是以所要求的容器作業和所使用的容器規格層級為基礎。

下表顯示容器建立作業的限制。

規範 限制
無無訊息內容 密鑰容器建立必須一律能夠顯示UI,例如 PIN 提示。
不覆寫現有的容器 如果所選智慧卡上已有指定的容器,請選擇另一張智慧卡或取消作業。

內容旗標

下表顯示用來作為容器建立作業限制的內容旗標。

旗標 描述
CRYPT_SILENT 此作業期間無法顯示任何UI。
CRYPT_MACHINE_KEYSET 在此作業期間不應使用任何快取數據。
CRYPT_VERIFYCONTEXT 智慧卡上只能存取公用數據。

除了容器作業和容器規格之外,您還必須在智慧卡選取期間考慮其他用戶選項,例如 CryptAcquireContext 旗標。

重要

CRYPT_SILENT旗標無法用來建立新的容器。

在無訊息內容中建立新的容器

應用程式可以使用 CRYPT_DEFAULT_CONTAINER_OPTIONAL呼叫基底 CSP、在無訊息內容中設定 PIN,然後在無訊息內容中建立新的容器。 這項作業的發生方式如下:

  1. 呼叫 CryptAcquireContext,方法是將 中的智慧卡卡片讀取器名稱傳遞為 II 容器規格層級類型,並指定 CRYPT_DEFAULT_CONTAINER_OPTIONAL 旗標
  2. 藉由指定 PP_KEYEXCHANGE_PINPP_SIGNATURE_PIN 和以 Null 結尾的 ASCII PIN 來呼叫 CryptSetProvParam。
  3. 釋放步驟 1 中取得的內容
  4. 使用呼叫 CryptAcquireContext CRYPT_NEWKEYSET,並指定類型 I 容器規格層級
  5. 呼叫 CryptGenKey 以建立金鑰

智慧卡選取行為

在下列某些案例中,系統會提示使用者插入智慧卡。 如果用戶內容是無訊息的,則此作業會失敗,而且不會顯示任何UI。 否則,為了回應UI,使用者可以插入智慧卡或選取 [取消]。 如果使用者取消作業,作業就會失敗。 流程圖會顯示 Windows 作業系統所執行的選取步驟。

智慧卡選取程式。

一般而言,智慧卡選取行為是由 SCardUIDlgSelectCard API 處理。 基底 CSP 會直接呼叫此 API 來與它互動。 基底 CSP 也會傳送回呼函式,其目的是篩選和比對候選智慧卡。 CryptAcquireContext 的呼叫端提供智慧卡比對資訊。 就內部而言,基底 CSP 會使用智慧卡序號、讀取器名稱和容器名稱的組合來尋找特定智慧卡。

每次呼叫 SCardUI * 可能會導致從候選智慧卡讀取其他資訊。 基底 CSP 智慧卡選取回呼會快取這項資訊。

讓智慧卡卡片閱讀機相符

針對類型 I 和類型 II 容器規格層級,智慧卡選取程式較不複雜,因為只有具名讀取器中的智慧卡可以視為相符專案。 比對智慧卡與智慧卡卡片閱讀機的程式如下:

  1. 尋找要求的智慧卡卡片閱讀機。 如果找不到,進程會失敗 (這需要依讀取器名稱進行快取搜尋)
  2. 如果讀取器中沒有智慧卡,系統會提示使用者插入智慧卡。 (這僅處於非敏感模式;如果呼叫是以無訊息模式進行,則會失敗)
  3. 僅針對容器規格層級 II,會決定所選智慧卡上的預設容器名稱
  4. 若要開啟現有的容器或刪除現有的容器,請尋找指定的容器。 如果在此智慧卡上找不到指定的容器,系統會提示使用者插入智慧卡
  5. 如果系統嘗試建立新的容器,如果指定的容器已經存在於此智慧卡上,則程式會失敗

讓智慧卡相符

針對容器規格層級 III 和 IV,會使用更廣泛的方法來比對適當的智慧卡與使用者內容,因為多個快取的智慧卡可能符合提供的準則。

開啟現有的預設容器 (沒有指定的讀取器)

注意

這項作業需要您搭配基底 CSP 使用智慧卡。

  1. 針對基底 CSP 所存取的每個智慧卡,以及快取句柄和容器資訊,基底 CSP 會尋找有效的預設容器。 已嘗試在快取的SCARDHANDLE上進行作業,以驗證其有效性。 如果智慧卡句柄無效,基底 CSP 會繼續搜尋新的智慧卡
  2. 如果在基底 CSP 快取中找不到相符的智慧卡,基底 CSP 會呼叫智慧卡子系統。 SCardUIDlgSelectCard () 與適當的回呼篩選器搭配使用,以尋找具有有效預設容器的相符智慧卡

開啟現有的 GUID 具名容器 (沒有指定的讀取器)

注意

這項作業需要您搭配基底 CSP 使用智慧卡。

  1. 針對已向基底 CSP 註冊的每個智慧卡,搜尋要求的容器。 嘗試在快取的 SCARDHANDLE 上進行作業,以驗證其有效性。 如果智慧卡句柄無效,智慧卡的序號會傳遞至 SCardUI * API 以繼續搜尋此特定智慧卡 (,而不只是容器名稱的一般相符專案)
  2. 如果在基底 CSP 快取中找不到相符的智慧卡,則會呼叫智慧卡子系統。 SCardUIDlgSelectCard() 與適當的回呼篩選器搭配使用,以尋找與所要求容器相符的智慧卡。 或者,如果智慧卡序號是從步驟 1 中的搜尋所產生,回呼篩選會嘗試比對序號,而不是容器名稱

建立新的容器 (沒有指定的讀取器)

注意

這項作業需要您搭配基底 CSP 使用智慧卡。

如果未快取 PIN,則不允許CRYPT_SILENT建立容器,因為至少必須提示使用者輸入 PIN。

對於其他作業,呼叫端可以取得預設容器CRYPT_DEFAULT_CONTAINER_OPTIONAL驗證內容,然後使用 CryptSetProvParam 進行呼叫,以快取使用者 PIN 以進行後續作業。

  1. 針對 CSP 已經知道的每個智慧卡,重新整理儲存的 SCARDHANDLE,並進行下列檢查:
    1. 如果智慧卡已移除,請繼續搜尋
    2. 如果智慧卡存在,但已經有具名容器,請繼續搜尋
    3. 如果智慧卡可供使用,但呼叫 CardQueryFreeSpace 表示智慧卡的儲存空間不足,無法使用其他密鑰容器,請繼續搜尋
    4. 否則,請使用符合上述容器建立準則的第一張可用智慧卡
  2. 如果在 CSP 快取中找不到相符的智慧卡,請呼叫智慧卡子系統。 用來篩選列舉智慧卡的回呼會驗證候選智慧卡還沒有具名容器,而且 CardQueryFreeSpace 指出智慧卡有足夠的空間可供其他容器使用。 如果找不到適合的智慧卡,系統會提示使用者插入智慧卡

刪除容器

  1. 如果指定的容器名稱是 NULL,則會刪除預設容器。 刪除預設容器會導致任意選取新的預設容器。 基於這個理由,不建議執行此作業
  2. 針對 CSP 已經知道的每個智慧卡,重新整理儲存的 SCARDHANDLE,並進行下列檢查:
    1. 如果智慧卡沒有具名容器,請繼續搜尋
    2. 如果智慧卡具有具名容器,但智慧卡句柄不再有效,請儲存相符智慧卡的序號,並將其傳遞至 SCardUI
  3. 如果在 CSP 快取中找不到相符的智慧卡,請呼叫智慧卡子系統。 用來篩選列舉智慧卡的回呼應該確認候選智慧卡具有具名容器。 如果因為先前的快取搜尋而提供序號,回呼應該在序號上篩選列舉的智慧卡,而不是在容器相符專案上篩選。 如果內容為非無訊息,且找不到適合的智慧卡,則會顯示提示使用者插入智慧卡的 UI

Windows 中的基底 CSP 和 KSP 架構

下圖顯示 Windows 作業系統所使用的密碼編譯架構。

密碼編譯架構。

Windows 中的基底 CSP 和智慧卡 KSP 屬性

注意

API 定義位於 WinCrypt.h 和 WinSCard.h。

屬性 描述
PP_USER_CERTSTORE - 用來傳回 HCERTSTORE 包含智慧卡上所有用戶憑證的
- 唯讀 (由 CryptGetProvParam) 使用
- 負責關閉證書存儲的呼叫者
- 使用 PKCS_7_ASN_ENCODING 或 編碼的憑證 X509_ASN_ENCODING
- CSP 應在憑證上設定KEY_PROV_INFO
- 證書存儲應假設為記憶體內部存放區
- 憑證應具有有效的 CRYPT_KEY_PROV_INFO 屬性
PP_ROOT_CERTSTORE - 和 所 CryptGetProvParamCryptSetProvParam 使用的讀取和寫入 ()
- 用來將跟證書的集合寫入智慧卡或傳回 HCERTSTORE,其中包含智慧卡的跟證書
- 主要用於使用智慧卡加入網域
- 負責關閉證書存儲的呼叫者
PP_SMARTCARD_READER - 唯讀 (由 CryptGetProvParam) 使用
- 傳回智慧卡卡片讀取器名稱作為 ANSI 字串串,用來建構完整的容器名稱 (也就是智慧卡卡片讀取器加上容器)
PP_SMARTCARD_GUID - 傳回智慧卡 GUID (也稱為序號) ,這應該是每個智慧卡的唯一
- 由憑證傳播服務用來追蹤跟證書的來源
PP_UI_PROMPT - 用來設定卡片插入對話框的 SCardUIDlgSelectCard 搜尋字串
- 設定整個進程時的持續性
- 唯寫 (僅供 CryptSetProvParam) 使用

對 Windows 中 CSP 的影響

密碼編譯服務提供者 (CSP) ,包括自定義智慧卡 CSP,仍會繼續受到支援,但不建議使用此方法。 使用現有的基底 CSP 和智慧卡 KSP 搭配智慧卡的智慧卡迷你驅動程式模型,可在效能和 PIN 和數據快取方面提供顯著的優點。 您可以將一個迷你驅動程式設定為在 CryptoAPI 和 CNG 層下運作。 這可從增強的密碼編譯支援中獲益,包括橢圓曲線密碼編譯和 AES。

如果智慧卡是由 CSP 和智慧卡迷你驅動程式註冊,則最近安裝的智慧卡會用來與智慧卡通訊。

撰寫智慧卡迷你驅動程式、CSP 或 KSP

只有在目前的智慧卡迷你驅動程序架構中無法使用特定功能時,才能撰寫 CSP 和 KSP。 例如,智慧卡迷你驅動程式架構支援硬體安全性模組,因此可以針對硬體安全性模組撰寫迷你驅動程式,而且除非需要支援未在基底 CSP 或智慧卡 KSP 中實作的演算法,否則可能不需要 CSP 或 KSP。

如需如何撰寫智慧卡迷你驅動程式、CSP 或 KSP 的詳細資訊,請參閱 智慧卡迷你驅動程式