Windows Hello

本文說明作為 Windows 10 和 Windows 11 作業系統一部分提供的新 Windows Hello 技術,並討論了開發人員如何實施該技術來保護其通用 Windows 平台 (UWP) 應用程式和後端服務。 它重點介紹了這些技術的特定功能,這些功能有助於減輕使用傳統認證產生的威脅,並提供有關在 Windows 10 和 Windows 11 部署過程中設計和部署這些技術的指導。

請注意,本文著重說明應用程式開發。 如需 Windows Hello 架構和實作詳細資料的詳細資訊,請參閱 TechNet 上的 Windows Hello 指南

如需完整的程式碼範例,請參閱 GitHub 上的 Windows Hello 程式碼範例

如需使用 Windows Hello 和支援驗證服務建立 UWP 應用程式的逐步解說,請參閱 Windows Hello 登入應用程式Windows Hello 登入服務一文。

1 簡介

資訊安全的基本假設是系統可以識別誰在使用它。 識別使用者可讓系統決定使用者是否經過正確識別 (該過程稱為驗證),然後決定經過正確驗證的使用者應該能夠執行哪些操作 (授權)。 全世界大多數部署的電腦系統都依賴使用者認證來做出驗證和授權決策,這代表這些系統依賴可重複使用的使用者建立的密碼作為其安全性的基礎。 經常被引用的格言是,驗證可以涉及「您知道的東西、您擁有的東西或您是什麼」,這巧妙地強調了這個問題:可重複使用的密碼本身就是一個驗證因素,因此任何知道密碼的人都可以冒充該使用者。

1.1 傳統認證的問題

自 1960 年代中期 Fernando Corbató 和他在麻省理工學院的團隊倡導引入密碼以來,使用者和管理員就不得不處理使用密碼進行使用者驗證和授權的問題。 隨著時間的推移,密碼儲存和使用的技術水平已經有所進步 (例如,安全雜湊和加鹽),但我們仍然面臨兩個問題。 密碼很容易複製,而且很容易竊取。 此外,實作錯誤可能會讓它們變得不安全,而且使用者很難平衡便利性和安全性。

1.1.1 認證竊取

密碼的最大風險很簡單:攻擊者可以輕鬆地竊取密碼。 輸入、處理或儲存密碼的每一個位置都容易受到攻擊。 例如,攻擊者可以透過竊聽應用程式伺服器的網路流量、在應用程式或裝置中植入惡意軟體、在裝置上記錄使用者按鍵或透過監視來從身分驗證伺服器竊取密碼或雜湊值的集合。請參閱使用者輸入的字元。 這些只是最常見的攻擊方法。

另一個相關風險是認證重新執行,攻擊者透過竊聽不安全的網路來擷取有效認證,然後重新執行該認證以冒充有效使用者。 大多數驗證協定 (包括 Kerberos 和 OAuth) 透過在認證交換過程中包含時間戳記來防止重新執行攻擊,但該策略僅保護驗證系統簽發的權杖,而不是使用者第一次取得票證的密碼。

1.1.2 認證重複使用

使用電子郵件地址作為使用者名稱的常見方法會使問題變得更糟。 成功從遭入侵系統恢復使用者名稱-密碼對的攻擊者,可以在其他系統上嘗試使用這組使用者名稱和密碼。 這種策略經常意外地有用,使攻擊者能夠從遭入侵的系統跳入其他系統。 使用電子郵件地址作為使用者名稱會導致其他問題,我們將在本指南的後面部分探討這些問題。

1.2 解決認證問題

解決密碼帶來的問題是很棘手的。 僅靠收緊密碼策略是不夠的; 使用者只能回收、共用或寫下密碼。 儘管使用者教育對於身分驗證安全至關重要,但僅靠教育也無法解決問題。

Windows Hello 透過驗證現有認證並建立生物特徵辨識或基於 PIN 的使用者手勢保護的裝置特定認證,以強大的雙重認證 (2FA) 取代密碼。 

2 什麼是 Windows Hello?

Windows Hello 是 Microsoft 為 Windows 10 和 Windows 11 中內建的新生物特徵辨識登入系統命名的名稱。 由於 Windows Hello 直接內建於作業系統中,因此允許透過臉部或指紋辨識來解鎖使用者的裝置。 當使用者提供其唯一的生物特徵辨識識別碼來存取裝置特定的認證時,就會進行驗證,這表示竊取裝置的攻擊者除非擁有 PIN,否則無法登入該裝置。 Windows 安全性認證儲存可保護裝置上的生物特徵辨識資料。 透過使用 Windows Hello 解鎖裝置,授權使用者可以存取其所有 Windows 體驗、應用程式、資料、網站和服務。

Windows Hello 驗證器稱為 Hello。 Hello 對於單一裝置和特定使用者的組合來說是唯一的。 它不會跨裝置漫遊,不會與伺服器或呼叫應用程式共用,並且無法輕鬆地從裝置中提取。 如果多個使用者共用一台裝置,每個使用者都需要設定自己的帳戶。 每個帳戶都會取得該裝置的唯一 Hello。 您可以將 Hello 視為可用於解鎖 (或釋放) 儲存認證的權杖。 Hello 本身不會向應用程式或服務驗證您的身分,但它會釋放可以進行驗證的認證。 換句話說,Hello 不是使用者認證,而是身分驗證過程的第二個因素。

2.1 Windows Hello 驗證

Windows Hello 為裝置提供了一種可靠的方法來識別單一使用者,它解決了使用者與要求服務或資料項目之間路徑的第一部分。 裝置識別出使用者後,仍然必須對使用者進行驗證,然後才能確定是否授予對所要求資源的存取權。 Windows Hello 提供強大的 2FA,該 2FA 已完全整合到 Windows 中,並透過特定裝置和生物特徵辨識手勢或 PIN 的組合取代可重複使用的密碼。

不過,Windows Hello 不僅僅是傳統 2FA 系統的替代方案。 它的概念類似於智慧卡:透過使用加密原語而不是字串比較來執行驗證,並且使用者的金鑰材料在防篡改硬體內是安全的。 Windows Hello 也不需要智慧卡部署所需的額外基礎結構元件。 特別是,如果您目前沒有公開金鑰基礎結構 (PKI),則不需要管理認證。 Windows Hello 結合了智慧卡的主要優點 (虛擬智慧卡的部署彈性和實體智慧卡的強大安全性),沒有任何缺點。

2.2 Windows Hello 的運作方式

當使用者在其電腦上設定 Windows Hello 時,它會在裝置上產生新的公開金鑰-私密金鑰組。 信賴平台模組 (TPM) 會產生並保護該私密金鑰。 如果裝置沒有 TPM 晶片,則私密金鑰由軟體加密和保護。 此外,支援 TPM 的裝置會產生一個資料區塊,可用於證明金鑰已繫結到 TPM。 例如,可以在您的解決方案中使用此證明資訊來決定是否向使用者授予不同的授權等級。

若要在裝置上啟用 Windows Hello,使用者必須在 Windows 設定中連接其 Azure Active Directory 帳戶或 Microsoft 帳戶。

2.2.1 如何保護金鑰

每當生成金鑰材料時,都必須保護它免受攻擊。 最可靠的保護方法是透過專用硬體。 使用硬體安全模組 (HSM) 為安全關鍵型應用程式產生、儲存和處理金鑰已有很長的歷史。 智慧卡是一種特殊類型的 HSM,與符合可信賴運算組織 TPM 標準的裝置一樣。 只要有可能,Windows Hello 實作就會利用板載 TPM 硬體來產生、儲存和處理金鑰。 但是,Windows Hello 和 Windows Hello for Work 不需要板載 TPM。

只要可行,Microsoft 建議使用 TPM 硬體。 TPM 可抵禦各種已知及潛在的攻擊,包括 PIN 碼暴力密碼破解攻擊。 TPM 也會在帳戶鎖定之後提供額外的保護層。 當 TPM 鎖定金鑰材料時,使用者必須重設 PIN。 重設 PIN 代表系統將刪除使用舊金鑰材料加密的所有金鑰和認證。

2.2.2 驗證

當使用者想要存取受保護的金鑰材料時,驗證流程的第一步是使用者輸入 PIN 或生物特徵辨識手勢來解鎖裝置,該流程有時稱為「釋放金鑰」。

應用程式永遠不能使用另一個應用程式的金鑰,也不能使用其他使用者的金鑰。 這些金鑰可用來簽署傳送至識別提供者或 IDP 的要求,以尋求對指定資源的存取。 應用程式可以使用特定的 API 來要求需要金鑰材料執行特定動作的作業。 透過這些 API 進行存取需要透過使用者手勢進行明確驗證,並且金鑰材料不會暴露給要求的應用程式。 相反地,應用程式會要求特定動作,例如簽署一段資料,然後 Windows Hello 層會處理實際工作並傳回結果。

2.3 準備實作 Windows Hello

現在我們已經基本了解了 Windows Hello 的運作方式,接下來讓我們看看如何在自己的應用程式中進行實作。

我們可以在各種場景實作使用 Windows Hello。 例如,在裝置上登入應用程式。 另一個常見的場景是針對服務進行驗證。 您將使用 Windows Hello,而不是使用登入名稱和密碼。 在接下來的章節中,我們將討論實作幾個不同的場景,包括如何使用 Windows Hello 對服務進行驗證,以及如何從現有的使用者名稱/密碼系統轉換為 Windows Hello 系統。

3 實作 Windows Hello

在本章中,我們會從沒有現有驗證系統的全新場景開始,並說明如何實作 Windows Hello。

下一節將說明如何從現有的使用者名稱/密碼系統移轉。 即使您對這一章更感興趣,您可能還是需要先仔細閱讀本章節以基本了解該流程和所需的程式碼。

3.1 註冊新使用者

首先,我們將體驗使用 Windows Hello 的全新服務,虛擬一個要在新裝置上註冊的新使用者。

第一步是確認使用者是否能夠使用 Windows Hello。 該應用程式會驗證使用者設定和機器功能,以確保它可以建立使用者識別碼金鑰。 如果應用程式確定使用者尚未啟用 Windows Hello,它會提示使用者在使用應用程式之前進行設定。

若要啟用 Windows Hello,使用者只需在 Windows 設定中設定 PIN,除非使用者已在開箱即用體驗 (OOBE) 期間進行設定。

以下程式碼行示範了一種簡單的方法,可檢查使用者是否設定了 Windows Hello。

var keyCredentialAvailable = await KeyCredentialManager.IsSupportedAsync();
if (!keyCredentialAvailable)
{
    // User didn't set up PIN yet
    return;
}

下一步是要求使用者提供註冊您服務的資訊。 您可以選擇詢問使用者的名字、姓氏、電子郵件地址和唯一使用者名稱。 您可以使用電子郵件地址作為唯一識別碼; 這可由您決定。

在本例中,我們使用電子郵件地址作為使用者的唯一識別碼。 使用者註冊後,您應該考慮傳送驗證電子郵件,以確保地址有效。 這為您提供了可在必要時重設帳戶的機制。

如果使用者已設定其 PIN 碼,應用程式會建立使用者的 KeyCredential。 應用程式也會取得選擇性金鑰證明資訊,以取得金鑰是在 TPM 上生成的加密證明。 產生的公開金鑰和選擇性證明會傳送到後端伺服器,以註冊正在使用的裝置。 每台裝置上產生的每個金鑰組都是唯一的。

建立 KeyCredential 的程式碼如下所示:

var keyCreationResult = await KeyCredentialManager.RequestCreateAsync(
    AccountId, KeyCredentialCreationOption.ReplaceExisting);

RequestCreateAsync 是建立公開金鑰和私密金鑰的部分。 如果裝置具有正確的 TPM 晶片,API 將要求 TPM 晶片建立私密金鑰和公開金鑰並儲存結果; 如果沒有可用的 TPM 晶片,作業系統將在程式碼中建立金鑰組。 應用程式無法直接存取已建立的私密金鑰。 建立金鑰組部分也是產生的證明資訊。 (有關證明的更多資訊,請參閱下一節。)

在裝置上建立金鑰組和證明資訊後,需要將公開金鑰、選擇性證明資訊和唯一識別碼 (例如電子郵件地址) 傳送到後端註冊服務,並儲存在後端。

若要允許使用者在多個裝置上存取應用程式,後端服務需要能夠為同一使用者儲存多個金鑰。 由於每個裝置的每個金鑰都是唯一的,因此我們會儲存所有連線到同一使用者的金鑰。 裝置識別碼可用於在驗證使用者身分時,協助最佳化伺服器部分。 我們將在下一章更詳細地討論這一點。

在後端儲存此資訊的資料庫結構描述範例看起來可能像這樣:

Windows Hello sample database schema

註冊邏輯可能如下所示:

Windows Hello registration logic

當然,您所收集註冊資訊中包含的身分識別資訊可能比這個簡易案例中的更多。 例如,如果您的應用程式存取安全服務 (例如銀行服務),則您需要在註冊過程中要求身分證明和其他資訊。 一旦滿足所有條件,該使用者的公開金鑰將儲存在後端,並用於使用者下次使用服務時進行驗證。

using System;
using System.Runtime;
using System.Threading.Tasks;
using Windows.Storage.Streams;
using Windows.Security.Credentials;

static async void RegisterUser(string AccountId)
{
    var keyCredentialAvailable = await KeyCredentialManager.IsSupportedAsync();
    if (!keyCredentialAvailable)
    {
        // The user didn't set up a PIN yet
        return;
    }

    var keyCreationResult = await KeyCredentialManager.RequestCreateAsync(AccountId, KeyCredentialCreationOption.ReplaceExisting);
    if (keyCreationResult.Status == KeyCredentialStatus.Success)
    {
        var userKey = keyCreationResult.Credential;
        var publicKey = userKey.RetrievePublicKey();
        var keyAttestationResult = await userKey.GetAttestationAsync();
        IBuffer keyAttestation = null;
        IBuffer certificateChain = null;
        bool keyAttestationIncluded = false;
        bool keyAttestationCanBeRetrievedLater = false;

        keyAttestationResult = await userKey.GetAttestationAsync();
        KeyCredentialAttestationStatus keyAttestationRetryType = 0;

        if (keyAttestationResult.Status == KeyCredentialAttestationStatus.Success)
        {
            keyAttestationIncluded = true;
            keyAttestation = keyAttestationResult.AttestationBuffer;
            certificateChain = keyAttestationResult.CertificateChainBuffer;
        }
        else if (keyAttestationResult.Status == KeyCredentialAttestationStatus.TemporaryFailure)
        {
            keyAttestationRetryType = KeyCredentialAttestationStatus.TemporaryFailure;
            keyAttestationCanBeRetrievedLater = true;
        }
        else if (keyAttestationResult.Status == KeyCredentialAttestationStatus.NotSupported)
        {
            keyAttestationRetryType = KeyCredentialAttestationStatus.NotSupported;
            keyAttestationCanBeRetrievedLater = true;
        }
    }
    else if (keyCreationResult.Status == KeyCredentialStatus.UserCanceled ||
        keyCreationResult.Status == KeyCredentialStatus.UserPrefersPassword)
    {
        // Show error message to the user to get confirmation that user
        // does not want to enroll.
    }
}

3.1.1 證明

建立金鑰組時,也可以選擇要求由 TPM 晶片產生的證明資訊。 此選擇性資訊可以作為註冊過程的一部分傳送到伺服器。 TPM 金鑰證明是一種以加密方式證明金鑰受 TPM 約束的通訊協定。 這種類型的證明可用於確保特定電腦的 TPM 中發生了特定的加密作業。

當伺服器收到產生的 RSA 金鑰、證明陳述式和 AIK 認證時,會驗證以下條件:

  • AIK 認證簽章有效。
  • AIK 認證鏈結到受信任的根目錄。
  • AIK 認證及其鏈結已針對 EKU OID「2.23.133.8.3」啟用 (易記名稱為為「證明身分識別金鑰認證」)。
  • AIK 認證具有時效性。
  • 鏈結中所有核發的 CA 認證均具有時效性且不會撤銷。
  • 證明陳述式的格式正確。
  • KeyAttestation blob 上的簽章使用 AIK 公開金鑰。
  • KeyAttestation blob 中包含的公開金鑰與用戶端隨證明陳述式一起傳送的 RSA 公開金鑰相符。

您的應用程式可能會根據這些條件為使用者指派不同的授權等級。 例如,如果其中一項檢查失敗,則可能不會註冊使用者,或者可能會限制使用者可以執行的動作。

3.2 使用 Windows Hello 登入

使用者在您的系統中註冊後,就可以使用該應用程式。 根據具體情況,您可以要求使用者先進行驗證才能開始使用應用程式,或只要求他們在開始使用後端服務後進行驗證。

3.3 強制使用者再次登入

在某些情況下,您可能會希望使用者在存取應用程式之前,或在應用程式內執行特定動作之前,證明自己是目前登入的人員。 例如,在銀行應用程式向伺服器傳送轉帳命令之前,您需要確保是使用者 (而不是找到登入裝置的人) 要執行交易。 您可以使用 UserConsentVerifier 類別強制使用者在您的應用程式中再次登入。 以下程式碼行將強制使用者輸入其認證。

以下程式碼行將強制使用者輸入其認證。

UserConsentVerificationResult consentResult = await UserConsentVerifier.RequestVerificationAsync("userMessage");
if (consentResult.Equals(UserConsentVerificationResult.Verified))
{
    // continue
}

當然,您也可以使用伺服器的質詢回應機制,該機制要求使用者輸入其 PIN 碼或生物特徵辨識認證。 這取決於您作為開發人員需要實作的場景。 此機制將會在下一節中介紹。

3.4 後端驗證

當應用程式嘗試存取受保護的後端服務時,該服務會向應用程式傳送質詢。 該應用程式會使用使用者的私密金鑰組質詢進行簽署,並將其傳送回伺服器。 由於伺服器已儲存該使用者的公開金鑰,因此它會使用標準加密 API 來確保訊息確實使用正確的私密金鑰進行簽署。 在客戶端,簽署是由 Windows Hello API 完成; 開發人員永遠無法存取任何使用者的私密金鑰。

除了檢查金鑰之外,該服務還可以檢查金鑰證明,並辨別金鑰在裝置上的儲存方式是否有任何限制。 例如,當裝置使用 TPM 來保護金鑰時,會比不使用 TPM 儲存金鑰的裝置更安全。 例如,後端邏輯可以決定在不使用 TPM 時,僅允許使用者轉移一定數量的資金以降低風險。

證明僅適用於具有 2.0 或更新版 TPM 晶片的裝置。 因此,您需要考慮到此資訊可能並非在所有裝置上都能使用。

用戶端工作流程看起來可能如下圖所示:

Windows Hello client workflow

當應用程式呼叫後端服務時,伺服器會傳送質詢。 質詢會使用以下程式碼進行簽署:

var openKeyResult = await KeyCredentialManager.OpenAsync(AccountId);

if (openKeyResult.Status == KeyCredentialStatus.Success)
{
    var userKey = openKeyResult.Credential;
    var publicKey = userKey.RetrievePublicKey();
    var signResult = await userKey.RequestSignAsync(message);

    if (signResult.Status == KeyCredentialStatus.Success)
    {
        return signResult.Result;
    }
    else if (signResult.Status == KeyCredentialStatus.UserPrefersPassword)
    {

    }
}

第一行 KeyCredentialManager.OpenAsync 將要求作業系統開啟金鑰控制代碼。 如果成功完成,您可以使用 KeyCredential.RequestSignAsync 方法對質詢訊息進行簽署。該方法將觸發作業系統透過 Windows Hello 要求使用者的 PIN 或生物特徵辨識資訊。 開發人員永遠無法存取使用者的私密金鑰。 這一切都透過 API 保持安全。

API 會要求作業系統使用私密金鑰組質詢進行簽署。 然後,系統會要求使用者輸入 PIN 碼或已設定的生物特徵辨識登入。 輸入正確的資訊後,系統可以要求 TPM 晶片執行加密功能,並對質詢進行簽署。 (或者,如果沒有可用的 TPM,請使用後援軟體解決方案)。 客戶端必須將已簽署的質詢傳回伺服器。

此序列圖中顯示了基本的質詢-回應流程:

Windows Hello challenge response

接下來,伺服器必須驗證簽章。 當您要求公開金鑰並將其傳送到伺服器以用於將來驗證時,它會位於 ASN.1 編碼的 publicKeyInfo blob 中。 如果您查看 GitHub 上的 Windows Hello 程式碼範例,您將看到有幫助程式類別來包裝 Crypt32 函數,以將 ASN.1 編碼的 blob 轉換為更常用的 CNG blob。 此 blob 包含公開金鑰演算法 (即 RSA) 和 RSA 公開金鑰。

在此範例中,我們將 ASN.1 編碼的 blob 轉換為 CNG blob 的原因是它可以與 CNG (/windows/desktop/SecCNG/cng-portal) 和 BCrypt API 一起使用。 如果您查詢 CNG blob,它將指向相關的 BCRYPT_KEY_BLOB 結構。 此 API 介面可用於 Windows 應用程式中的驗證和加密。 ASN.1 是用於通訊可序列化資料結構的記錄標準,通常用於公開金鑰加密和認證。 這就是為什麼公開金鑰資訊以這種方式傳回的原因。 公開金鑰是 RSA 金鑰; 這就是 Windows Hello 在簽署資料時所使用的演算法。

取得 CNG blob 後,您需要根據使用者的公開金鑰驗證簽章質詢。 由於每個人都使用自己的系統或後端技術,因此無法用通用方法來實作此邏輯。 我們使用 SHA256 作為雜湊演算法,並使用 Pkcs1 作為 SignaturePadding,因此請確保在驗證來自客戶端的簽章回應時使用該演算法。 再次,請參閱範例以了解在 .NET 4.6 中的伺服器上執行此操作的方法,但通常看起來會像這樣:

using (RSACng pubKey = new RSACng(publicKey))
{
    retval = pubKey.VerifyData(originalChallenge, responseSignature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
}

我們會讀取已儲存的公開金鑰,也就是 RSA 金鑰。 我們會使用公開金鑰驗證簽署的質詢訊息,如果檢查通過,我們就會向使用者授權。 如果使用者通過驗證,應用程式可以正常呼叫後端服務。

完整的程式碼可能如下所示:

using System;
using System.Runtime;
using System.Threading.Tasks;
using Windows.Storage.Streams;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Security.Credentials;

static async Task<IBuffer> GetAuthenticationMessageAsync(IBuffer message, String AccountId)
{
    var openKeyResult = await KeyCredentialManager.OpenAsync(AccountId);

    if (openKeyResult.Status == KeyCredentialStatus.Success)
    {
        var userKey = openKeyResult.Credential;
        var publicKey = userKey.RetrievePublicKey();
        var signResult = await userKey.RequestSignAsync(message);
        if (signResult.Status == KeyCredentialStatus.Success)
        {
            return signResult.Result;
        }
        else if (signResult.Status == KeyCredentialStatus.UserCanceled)
        {
            // Launch app-specific flow to handle the scenario 
            return null;
        }
    }
    else if (openKeyResult.Status == KeyCredentialStatus.NotFound)
    {
        // PIN reset has occurred somewhere else and key is lost.
        // Repeat key registration
        return null;
    }
    else
    {
        // Show custom UI because unknown error has happened.
        return null;
    }
}

實作正確的質詢-回應機制不在本文件的討論範圍內,但也需要注意此主題,以便成功建立安全機制來防止重新執行攻擊或中間人攻擊等事件。

3.5 註冊另一個裝置

如今,使用者經常會在多個裝置上安裝相同的應用程式。 當在多個裝置上使用 Windows Hello 時,這是如何運作的?

使用 Windows Hello 時,每個裝置都會建立一個唯一私密金鑰和公開金鑰集。 這代表如果您希望使用者能夠使用多個裝置,您的後端必須能夠儲存該使用者的多個公開金鑰。 如需資料表結構的範例,請參閱 2.1節的資料庫圖。

註冊其他裝置與第一次註註冊使用者的流程幾乎相同。 您仍然需要確保註冊此新裝置的使用者確實是其聲稱的使用者。 您可以使用現今使用的任何雙重要素驗證機制來執行此動作。 可用多種方式來安全地完成這項作業。 這要視您的案例而定。

例如,如果您仍然使用登入名稱和密碼,您可以使用它來驗證使用者身分,並要求他們使用其中一種驗證方法,例如簡訊或電子郵件。 如果您沒有登入名稱和密碼,您也可以使用已註冊的裝置之一並向該裝置上的應用程式傳送通知。 MSA 驗證器應用程式就是一個例子。 簡而言之,您應該使用通用的 2FA 機制為使用者註冊額外的裝置。

註冊新裝置的代碼與首次註冊使用者 (在應用程式內) 完全相同。

var keyCreationResult = await KeyCredentialManager.RequestCreateAsync(
    AccountId, KeyCredentialCreationOption.ReplaceExisting);

為了讓使用者能更容易識別哪些裝置已註冊,您可以選擇傳送裝置名稱或其他識別碼作為註冊的一部分。 如果您想在後端實作一項服務,讓使用者可以在裝置遺失時取消註冊裝置,那這也會很實用。

3.6 在您的應用程式中使用多個帳戶

除了支援單一帳戶的多個裝置之外,在單一應用程式中支援多個帳戶也很常見。 例如,您可能要從應用程式內連接到多個 Twitter 帳戶。 使用 Windows Hello,您可以建立多個金鑰組,並在您的應用程式內支援多個帳戶。

實現此目的的一種方法是將上一章中描述的使用者名稱或唯一識別碼保存在隔離儲存區中。 如此一來,每次建立新帳戶時,都會將帳戶識別碼儲存在隔離儲存區中。

在應用程式 UI 中,您可允許使用者選擇先前建立的帳戶,或註冊新帳戶。 建立新帳戶的流程與先前所述相同。 選擇帳戶只需在螢幕上列出已儲存的帳戶即可。 使用者選擇帳戶後,請使用帳戶識別碼在您的應用程式中登入使用者:

var openKeyResult = await KeyCredentialManager.OpenAsync(AccountId);

其餘流程與先前所述的相同。 必須說清楚的是,這些帳戶都受到相同 PIN 或生物特徵辨識手勢的保護,因為在此案例中,它們是在具有相同 Windows 帳戶的單一裝置上使用的。

4 將現有系統移轉到 Windows Hello

在本節中,我們將討論現有的通用 Windows 平台應用程式和後端系統,該系統使用儲存使用者名稱和雜湊密碼的資料庫。 這些應用程式會在應用程式啟動時收集使用者的認證,並在後端系統傳回身分驗證質詢時使用它們。

在這裡,我們將說明需要變更或取代哪些部分,才能使 Windows Hello 正常運作。

我們已經在前面的章節中說明了大部分技術。 將 Windows Hello 新增至現有系統需要在程式碼的註冊和驗證部分新增幾個不同的流程。

一種方法是讓使用者選擇何時升級。 當使用者登入應用程式並且您偵測到該應用程式和作業系統能夠支援 Windows Hello 後,您可以詢問使用者是否想要升級認證以使用這個現代且更安全的系統。 您可以使用以下程式碼來檢查使用者是否能夠使用 Windows Hello。

var keyCredentialAvailable = await KeyCredentialManager.IsSupportedAsync();

UI 看起來可能會像這樣:

Windows Hello ui

如果使用者選擇開始使用 Windows Hello,您將建立先前所述的 KeyCredential。 後端註冊伺服器會將公開金鑰和選擇性證明陳述式新增至資料庫。 由於使用者已經透過使用者名稱和密碼進行了驗證,因此伺服器可以將新認證連結到資料庫中的目前使用者資訊。 可以用與先前所述範例相同的資料庫模型。

如果應用程式能夠建立使用者 KeyCredential,它會將使用者識別碼儲存在隔離儲存區中,以便使用者可以在應用程式再次啟動後從清單中選擇此帳戶。 接下來的流程將與先前章節中所述的範例完全相同。

移轉到完整 Windows Hello 方案的最後一步是停用應用程式中的登入名稱和密碼選項,並從資料庫中移除已儲存的雜湊密碼。

5 摘要

Windows 10 和 Windows 11 引進了更高階的安全性,並且能夠輕鬆實施。 Windows Hello 提供了一種新的生物特徵辨識登入系統,可以識別使用者並能主動阻止規避適當識別的嘗試。 然後,它可以提供多層金鑰和憑證,這些金鑰和憑證永遠不會在可信賴平台模組之外顯示或使用。 此外,透過選擇性使用證明身分識別金鑰和憑證,可進一步提供一層安全性。

作為開發人員,您可以使用有關這些技術的設計和部署的指南,輕鬆地將安全性驗證新增至 Windows 10 和 Windows 11 部署中,以保護應用程式和後端服務。 所需的程式碼最少且易於理解。 Windows 10 和 Windows 11 能承擔繁重的工作。

靈活的實作選項可讓 Windows Hello 取代您現有的驗證系統,或與您現有的驗證系統一起運作。 整個部署體驗既輕鬆又經濟實惠。 部署 Windows 10 和 Windows 11 安全性不需要額外的基礎結構。 透過作業系統內建的 Microsoft Hello,Windows 10 和 Windows 11 為現代開發人員面臨的驗證問題提供了最安全的解決方案。

任務完成! 您讓網路變得更安全了!

6 資源

6.1 文章和範例程式碼

6.2 術語

詞彙 定義
AIK 證明身分金鑰用於透過對不可移轉金鑰的屬性進行簽署,並將屬性和簽章提供給依賴方進行驗證來提供此類加密證明 (TPM 金鑰證明)。 產生的簽名稱為「證明陳述式」。 由於簽章是使用 AIK 私密金鑰建立的 (只能在建立它的 TPM 中使用),信賴認證者可以相信經過證明的金鑰確實是不可移轉的,並且不能在該 TPM 之外使用。
AIK 憑證 AIK 憑證用於證明 TPM 中是否存在 AIK。 它也可用於證明 AIK 認證的其他金鑰源自於該特定 TPM。
IDP IDP 是身分識別提供者。 例如 Microsoft 為 Microsoft Accounts 所建置的 IDP。 每次應用程式需要向 MSA 進行驗證時,它都可以呼叫 MSA IDP。
PKI 公開金鑰基礎設施通常用於指向組織本身託管的環境,並負責建立金鑰、撤銷金鑰等。
TPM 可信賴平台模組可用於建立加密公開金鑰/私密金鑰組,使得私密金鑰永遠不會在 TPM 之外顯示或使用 (即,金鑰是不可移轉的)。
TPM 金鑰證明 一種以加密方式證明金鑰受 TPM 約束的通訊協定。 這種類型的證明可用於確保特定電腦的 TPM 中發生了特定的加密作業