安全開發 Windows 應用程式的簡介
此介紹文章可協助應用架構師和開發人員更了解各種 Windows 10 平台功能,這些功能可加速建立安全的通用 Windows 平台 (UWP) 應用程式。 它詳細介紹如何使用以下每個階段可用的 Windows 安全功能:身分驗證、動態資料和靜態資料。 您可以透過查看每章中包含的其他資源來找到有關每個主題的更深入的資訊。
1 簡介
開發安全應用程式可能是一項挑戰。 在當今行動、社交、雲端和複雜企業應用程式的快節奏世界中,客戶期望應用程式能夠比以往更快地提供和更新。 他們還使用多種類型的裝置,進一步增加了建立應用程式體驗的複雜性。 如果您針對 Windows 通用 Windows 平台 (UWP) 建置,可能包含傳統桌面電腦、膝上型電腦、平板電腦和行動裝置清單;此外,還有橫跨物聯網、Xbox One、Microsoft Surface Hub 和 HoloLens 的新裝置清單不斷增加。 作為開發人員,您必須確保您的應用程式在涉及的所有平台或裝置上安全地通訊和儲存資料。
以下是使用 Windows 安全性功能的一些優點。
- 您將針對安全性元件和技術使用一致的 API,在所有支援 Windows 的裝置上標準化安全性。
- 與實作自訂程式碼來覆蓋這些安全場景相比,您編寫、測試和維護的程式碼更少。
- 您的應用程式變得更加穩定和安全,因為您使用作業系統來控制應用程式存取其資源以及本地或遠端系統資源的方式。
在身分驗證期間,將驗證請求存取特定服務的使用者的身分。 Windows Hello 是 Windows 中的元件,可協助在 Windows 應用程式中建立更安全的驗證機制。 有了它,您可以使用個人識別碼 (PIN) 或使用者指紋、臉部或虹膜等生物識別技術為您的應用程式實施多重身分驗證。
傳輸中的資料是指連接以及透過該連線傳輸的訊息。 一個範例是使用 Web 服務從遠端伺服器檢索資料。 使用安全通訊端層 (SSL) 和安全超文本傳輸協定 (HTTPS) 可確保連線的安全性。 防止中間方存取這些訊息,或防止未經授權的應用程式與網路服務通信,是保護傳輸中資料的關鍵。
最後,靜態資料涉及駐留在記憶體或儲存媒體上的資料。 Windows 應用程式具有應用程式模型,可防止應用程式之間未經授權的數據存取,並提供加密 API 來進一步保護裝置上的數據。 名為 Credential Locker 的功能可用於在裝置上安全地儲存使用者憑證,作業系統會阻止其他應用程式存取它們。
2 認證因素
為了保護資料,必須識別請求存取資料的人員並授權其存取他們請求的資料資源。 識別使用者的過程稱為身分驗證,確定資源的存取權限的過程稱為授權。 這些是緊密相關的操作,對於使用者來說它們可能難以區分。 它們可以是相對簡單或複雜的操作,這取決於許多因素:例如,資料是駐留在一台伺服器上還是分佈在多個系統上。 提供身分驗證和授權服務的伺服器稱為身分提供者。
為了使用特定服務和/或應用程式對自己進行身分驗證,使用者使用由他們知道的東西、他們擁有的東西和/或他們是什麼東西組成的憑證。 其中每一個都稱為身分驗證因素。
- 使用者知道的內容通常是密碼,但也可以是個人識別碼 (PIN) 或「秘密」問答配對。
- 使用者最常擁有的東西是硬體儲存裝置,例如包含使用者獨有的認證資料的 USB 隨身碟。
- 使用者的身分通常包含他們的指紋,但使用者的語音、臉部、眼睛特徵或行為模式等越來越流行的因素。 當儲存為資料時,這些測量結果稱為生物識別技術。
使用者建立的密碼本身就是一個身分驗證因素,但這通常還不夠;任何知道密碼的人都可以冒充擁有該密碼的使用者。 智慧卡可以提供更高等級的安全性,但它可能會被盜、遺失或放錯地方。 可以透過指紋或目視掃描對使用者進行身分驗證的系統可能會提供最高、最方便的安全級別,但它需要昂貴且專用的硬體 (例如,用於臉部辨識的 Intel RealSense 攝影機),而這些硬體可能不可用給所有使用者。
設計系統使用的身分驗證方法是資料安全的一個複雜而重要的方面。 一般來說,在身分驗證中使用的因素越多,系統就越安全。 同時,身分驗證必須可用。 使用者通常一天會登入多次,因此程序必須快速。 您選擇的身分驗證類型是安全性和易用性之間的權衡;單因素身分驗證是最不安全且最容易使用的,多因素身分驗證變得更安全,但隨著添加更多因素而變得更加複雜。
2.1 單因子認證
這種形式的身分驗證是基於單一使用者憑證。 這通常是密碼,但也可能是個人識別碼 (PIN)。
這是單因素身分驗證的過程。
- 使用者向身分提供者提供使用者名稱和密碼。 身分提供者是驗證使用者身分的伺服器程序。
- 身分提供者檢查使用者名稱和密碼是否與系統中儲存的使用者名稱和密碼相同。 在大多數情況下,密碼將被加密,以提供額外的安全性,以便其他人無法讀取它。
- 身分提供者傳回身分驗證狀態,指示身分驗證是否成功。
- 如果成功,資料交換就會開始。 如果失敗,則必須重新驗證使用者。
如今,這種身分驗證方法是各種服務中最常使用的一種。 當用作唯一的身分驗證手段時,它也是最不安全的身分驗證形式。 密碼複雜性要求、「秘密問題」和定期變更密碼可以使密碼使用更加安全,但它們會給使用者帶來更多負擔,並且不能有效威懾駭客。
密碼面臨的挑戰是,與具有多個因素的系統相比,成功猜測密碼更容易。 如果他們從小型網路商店竊取了包含使用者帳戶和雜湊密碼的資料庫,他們就可以使用其他網站上使用的密碼。 使用者傾向於一直重複使用帳戶,因為複雜的密碼很難記住。 對於 IT 部門來說,管理密碼還帶來了必須提供重置機制、需要頻繁更新密碼以及以安全方式儲存密碼的複雜性。
儘管存在所有缺點,單因素身分驗證使使用者可以控制憑證。 他們會建立並加以修改,並且身分驗證過程只需要鍵盤。 這是區分單因素身分驗證和多因素身分驗證的主要方面。
2.1.1 Web 驗證代理人
如前所述,IT 部門密碼身分驗證的挑戰之一是管理使用者名稱/密碼基礎、重置機制等的額外開銷。方式提供身分驗證: OAuth,一種開放的身分驗證標準。
使用 OAuth,IT 部門可以有效地「外包」使用使用者名稱和密碼維護資料庫的複雜度、重設密碼功能等到 Facebook、X 或Microsoft等第三方識別提供者。
使用者在這些平台上可以完全控制自己的身分,但應用程式可以在使用者經過身分驗證並徵得他們的同意後,向提供者請求權杖,該權杖可用於授權經過身分驗證的使用者。
Windows 中的 Web 驗證代理人提供一組 API 和基礎結構,讓應用程式使用 OAuth 和 OpenID 等驗證和授權通訊協定。 應用程式可以透過 WebAuthenticationBroker API 啟動驗證操作,從而傳回 WebAuthenticationResult。 下圖顯示了通訊流程的概述。
該應用程式充當代理,透過應用程式中的 Web 檢視啟動與身分提供者的身分驗證。 當身分提供者對使用者進行身分驗證後,它會向應用程式傳回一個權杖,該權杖可用於從身分提供者請求有關使用者的資訊。 作為安全措施,應用程式必須先向身分提供者註冊,然後才能與身分提供者代理驗證流程。 每個提供者的註冊步驟都不同。
以下是呼叫 WebAuthenticationBroker API 與提供者通訊的一般工作流程。
- 建構要傳送到身分提供者的請求字串。 每個 Web 服務的字串數量以及每個字串中的信息都不同,但它通常包含兩個 URI 字串,每個字串都包含一個 URL:一個用於傳送身分驗證請求,另一個用於在授權後將使用者重新導向到該字串。
- 呼叫 WebAuthenticationBroker.AuthenticateAsync,傳入請求字串,然後等待身分提供者的回應。
- 呼叫 WebAuthenticationResult.ResponseStatus 以取得收到回應時的狀態。
- 如果通訊成功,則處理身分提供者傳回的回應字串。 如果失敗,請處理錯誤。
如果通訊成功,則處理身分提供者傳回的回應字串。 如果失敗,請處理錯誤。
此程式的 C# 程式碼範例如下。 如需資訊和詳細的逐步解說,請參閱 WebAuthenticationBroker。 如需完整的程式碼範例,請參閱 GitHub 上的 WebAuthenticationBroker 範例。
string startURL = "https://<providerendpoint>?client_id=<clientid>";
string endURL = "http://<AppEndPoint>";
var startURI = new System.Uri(startURL);
var endURI = new System.Uri(endURL);
try
{
WebAuthenticationResult webAuthenticationResult =
await WebAuthenticationBroker.AuthenticateAsync(
WebAuthenticationOptions.None, startURI, endURI);
switch (webAuthenticationResult.ResponseStatus)
{
case WebAuthenticationStatus.Success:
// Successful authentication.
break;
case WebAuthenticationStatus.ErrorHttp:
// HTTP error.
break;
default:
// Other error.
break;
}
}
catch (Exception ex)
{
// Authentication failed. Handle parameter, SSL/TLS, and
// Network Unavailable errors here.
}
2.2 多重身分驗證
多因素身分驗證使用多個身分驗證因素。 通常,會是「您知道的東西」(例如密碼) 與「您擁有的東西」 (可以是行動電話或智慧卡) 結合在一起。 即使攻擊者發現了使用者的密碼,如果沒有裝置或卡片,該帳戶仍然無法存取。 如果只有裝置或卡片被洩露,那麼沒有密碼對攻擊者來說是沒有用的。 因此,多因素身分驗證比單因素身分驗證更安全,但也更複雜。
使用多重身分驗證的服務通常會讓使用者選擇如何接收第二個憑證。 此類身分驗證的一個範例是常用的流程,其中使用簡訊將驗證碼傳送到使用者的手機。
- 使用者向身分提供者提供使用者名稱和密碼。
- 身分提供者依照單一因素授權驗證使用者名稱和密碼,然後尋找系統中儲存的使用者手機號碼。
- 伺服器將包含產生的驗證碼的簡訊傳送到使用者的手機。
- 使用者向身分提供者提供驗證碼;透過呈現給使用者的表格。
- 身分提供者傳回一個身分驗證狀態,指示兩個憑證的身分驗證是否成功。
- 如果成功,資料交換就會開始。 否則,必須重新驗證使用者身分。
如您所見,此過程也與單因素身分驗證不同,因為第二個使用者憑證將傳送給使用者,而不是由使用者建立或提供。 因此,使用者無法完全控制必要的憑證。 當智慧卡用作第二個憑證時,這也適用:組織負責建立並將其提供給使用者。
2.2.1 Azure Active Directory
Azure Active Directory (Azure AD) 是一種基於雲端的身分和存取管理服務,可作為單一因素或多因素身分驗證中的身分提供者。 Azure AD 驗證可以使用或不使用驗證碼。
雖然Azure AD也可以實現單一因素身分驗證,但企業通常需要更高安全性的多因素身分驗證。 在多重驗證配置中,使用 Azure AD 帳戶進行驗證的使用者可以選擇將驗證碼作為 SMS 訊息傳送至其手機或 Azure Authenticator 行動應用程式。
此外,Azure AD 還可以用作 OAuth 提供程序,為標準使用者提供跨各種平台的應用程式的身分驗證和授權機制。 要了解詳細資訊,請參閱 Azure Active Directory 和 Azure 上的多重驗證。
2.4 Windows Hello
在 Windows 中,操作系統內建方便的多重要素驗證機制。 Windows Hello 是 Windows 內建的新生物特徵辨識登入系統。 由於 Windows Hello 直接內建於作業系統中,因此允許透過臉部或指紋辨識來解鎖使用者的裝置。 Windows 安全性認證儲存可保護裝置上的生物特徵辨識資料。
Windows Hello 為裝置提供了一種可靠的方法來識別單一使用者,它解決了使用者與要求服務或資料項目之間路徑的第一部分。 裝置識別出使用者後,仍然必須對使用者進行驗證,然後才能確定是否授予對所要求資源的存取權。 Windows Hello 還提供強大的雙重認證 (2FA),完全整合到 Windows 中,並透過特定裝置和生物辨識手勢或 PIN 的組合取代可重複使用的密碼。 PIN 由使用者在其 Microsoft 帳戶註冊過程中指定。
不過,Windows Hello 不僅僅是傳統 2FA 系統的替代方案。 它的概念類似於智慧卡:透過使用加密原語而不是字串比較來執行驗證,並且使用者的金鑰材料在防篡改硬體內是安全的。 Microsoft Hello 也不需要智慧卡部署所需的額外基礎結構元件。 特別是,如果您目前沒有公開金鑰基礎結構 (PKI),則不需要管理認證。 Windows Hello 結合了智慧卡的主要優點 (虛擬智慧卡的部署彈性和實體智慧卡的強大安全性),沒有任何缺點。
裝置必須先向 Windows Hello 註冊,使用者才能向 Windows Hello 進行驗證。 Windows Hello 使用非對稱 (公鑰/私鑰) 加密,其中一方使用公鑰來加密另一方可以使用私鑰解密的資料。 對於 Windows Hello,它會建立一組公鑰/私鑰對,並將私鑰寫入裝置的可信任平台模組 (TPM) 晶片。 裝置註冊後,UWP 應用程式可以呼叫系統 API 來檢索使用者的公鑰,該公鑰可用於在伺服器上註冊使用者。
應用程式的註冊工作流程可能如下所示:
您收集的註冊資訊可能包含比這個簡單場景中更多的識別資訊。 例如,如果您的應用程式存取安全服務 (例如銀行服務),則您需要在註冊過程中要求身分證明和其他資訊。 一旦滿足所有條件,該使用者的公開金鑰將儲存在後端,並用於使用者下次使用服務時進行驗證。
如需 Windows Hello 的詳細資訊,請參閱 Windows Hello 企業版 概觀和 Windows Hello 開發人員指南。
3 動態資料安全方法
傳輸中資料安全方法適用於連接到網路的裝置之間傳輸的資料。 資料可以在私人企業內部網路的高安全環境中的系統之間傳輸,或在非安全的網路環境中的用戶端和網路服務之間傳輸。 Windows 應用程式可透過其網路 API 支援 SSL 之類的標準,並使用 Azure API 管理 等技術,讓開發人員能夠確保其應用程式的適當安全性層級。
3.1 遠端系統認證
與遠端電腦系統通訊的一般情況有兩種。
- 本機伺服器透過直接連線對使用者進行身分驗證。 例如,當伺服器和用戶端位於公司內部網路上。
- Web 服務透過 Internet 通訊。
Web 服務通訊的安全要求比直連場景更高,因為資料不再只是安全網路的一部分,惡意攻擊者攔截資料的可能性也更高。 由於各種類型的裝置將存取該服務,因此它們很可能已建置為 RESTful 服務,而不是 WCF,例如,這代表對服務的身分驗證和授權也帶來了新的挑戰。 我們將討論安全遠端系統通訊的兩個要求。
第一個要求是訊息機密性:用戶端和 Web 服務之間傳遞的資訊 (例如,使用者的身分和其他個人資訊) 在傳輸過程中不得被第三方讀取。 這通常是透過加密傳送訊息的連接以及加密訊息本身來實現的。 在私鑰/公鑰加密中,公鑰可供任何人使用,並用於加密要傳送到特定接收者的訊息。 私鑰僅由接收者持有,用於解密訊息。
第二個要求是訊息完整性:用戶端和 Web 服務必須能夠驗證它們收到的訊息是否是對方打算傳送的訊息,並且訊息在傳輸過程中沒有被變更。 這是透過使用數位簽署和憑證身分驗證對訊息進行簽名來完成的。
3.2 SSL 連線
為了建立和維護與用戶端的安全連接,Web 服務可以使用安全超文本傳輸協定 (HTTPS) 支援的安全通訊端層 (SSL)。 SSL 透過支援公鑰加密和伺服器憑證來提供訊息機密性和完整性。 SSL 已被傳輸層安全性 (TLS) 取代,但 TLS 通常被隨意稱為 SSL。
當用戶端請求存取伺服器上的資源時,SSL 會啟動與伺服器的協商過程。 這稱為 SSL 交握。 加密等級、一組公共和私有加密金鑰以及用戶端和伺服器憑證中的身分資訊被商定為 SSL 連線期間所有通訊的基礎。 此時伺服器可能也要求用戶端進行身分驗證。 連線建立後,所有訊息都會使用協商的公鑰進行加密,直到連線關閉。
3.2.1 SSL 固定
雖然 SSL 可以使用加密和憑證來提供訊息機密性,但它無法驗證與用戶端通訊的伺服器是否正確。 未經授權的第三方可以模仿伺服器的行為,攔截用戶端傳輸的敏感資料。 為了防止這種情況,使用稱為 SSL pinning 的技術來驗證伺服器上的憑證是否是用戶端期望和信任的憑證。
在應用程式中實作 SSL 固定有幾種不同的方法,每種方法都有自己的優點和缺點。 最簡單的方法是透過應用程式包清單中的憑證宣告。 此宣告使應用程式套件能夠安裝數位憑證並指定對它們的獨佔信任。 這導致僅允許在憑證鏈中具有相應憑證的應用程式和伺服器之間建立 SSL 連線。 該機制還可以安全地使用自簽名認證,因為不需要第三方依賴受信任的公共憑證頒發機構。
為了更好地控制驗證邏輯,可以使用 API 來驗證伺服器回應 HTTPS 請求而傳回的憑證。 請注意,此方法需要傳送請求並檢查回應,因此請務必在實際傳送請求中的敏感資訊之前將其新增為驗證。
以下 C# 程式碼說明了這種 SSL 固定方法。 ValidateSSLRoot 方法使用 HttpClient 類別來執行 HTTP 請求。 用戶端傳送回應之後,它會使用 RequestMessage.TransportInformation.ServerIntermediateCertificates 集合來檢查伺服器傳回的憑證。 然後,用戶端可以使用其中包含的指紋來驗證整個憑證鏈。 此方法確實需要在伺服器憑證過期並續訂時在應用程式中更新憑證指紋。
private async Task ValidateSSLRoot()
{
// Send a get request to Bing
var httpClient = new HttpClient();
var bingUri = new Uri("https://www.bing.com");
HttpResponseMessage response =
await httpClient.GetAsync(bingUri);
// Get the list of certificates that were used to
// validate the server's identity
IReadOnlyList<Certificate> serverCertificates = response.RequestMessage.TransportInformation.ServerIntermediateCertificates;
// Perform validation
if (!ValidateCertificates(serverCertificates))
{
// Close connection as chain is not valid
return;
}
// Validation passed, continue with connection to service
}
private bool ValidateCertificates(IReadOnlyList<Certificate> certs)
{
// In this example, we iterate through the certificates
// and check that the chain contains
// one specific certificate we are expecting
foreach (var cert in certs)
{
byte[] thumbprint = cert.GetHashValue();
// Check if the thumbprint matches whatever you
// are expecting
var expected = new byte[] { 212, 222, 32, 208, 94, 102,
252, 83, 254, 26, 80, 136, 44, 120, 219, 40, 82, 202,
228, 116 };
// ThumbprintMatches does the byte[] comparison
if (ThumbprintMatches(thumbprint, expected))
{
return true;
}
}
return false;
}
3.3 發布並保護對 REST API 的存取
為了確保對 Web 服務的授權訪問,每次呼叫 API 時都必須進行身分驗證。 當 Web 服務透過 Web 公開時,能夠控制效能和規模也是需要考慮的因素。 Azure API 管理是一項可以協助在 Web 上公開 API 的服務,同時提供三個層級的功能。
API 的發布者/管理員可以透過 Azure API 管理的發布者入口網站輕鬆設定 API。 在這裡,可以建立 API 集並管理對它們的訪問,以控制誰有權存取哪些 API。
想要存取這些 API 的開發人員 可以透過開發人員入口網站提出要求,它可以立即提供存取權,或要求發行者/系統管理員核准。 開發人員也可以在開發人員入口網站中查看 API 文件和範例程式碼,以快速採用 Web 服務提供的 API。
這些開發人員建立的應用程式接著會透過 Azure API 管理 所提供的 Proxy 存取 API。 代理既提供了一層模糊性,隱藏了發布者/管理員伺服器上 API 的實際端點,也可以包含 API 轉換等附加邏輯,以確保當對一個 API 的呼叫重新導向到其他。 它還可以使用 IP 篩選來阻止源自特定 IP 域或域集的 API 呼叫。 Azure API 管理也透過使用一組稱為 API 金鑰的公鑰來對每個 API 呼叫進行驗證和授權,從而確保其 Web 服務的安全性。 當授權失敗時,對 API 及其支援的功能的存取將被阻止。
Azure API 管理還可以減少對服務的 API 呼叫次數 (稱為限制的過程),以最佳化 Web 服務的效能。 要了解更多信息,請查看 Azure API 管理和 AzureCon 2015 上的 Azure API 管理。
4 靜態資料安全方法
當資料到達裝置時,我們稱之為「靜態資料」。這些資料需要以安全的方式儲存在裝置上,以便未經授權的使用者或應用程式無法存取。 Windows 中的應用程式模型會執行許多動作,以確保任何應用程式所儲存的數據都只能存取該應用程式,同時提供必要的 API 來共用數據。 還可以使用其他 API 來確保資料可以加密並且憑證可以安全地儲存。
4.1 Windows 應用程式模型
傳統上,Windows 從來沒有應用程式的定義。 它通常被稱為可執行檔 (.exe),這從不包括安裝、狀態儲存、執行長度、版本控制、作業系統整合或應用程式到應用程式的通訊。 透過 Windows 平台模型定義了一個涵蓋安裝、執行環境、資源管理、更新、資料模型和解除安裝的應用程式模型。
Windows 10 應用程式在容器中執行,這代表它們預設具有有限的權限 (使用者可以要求和授予其他權限)。 例如,如果應用程式想要存取系統上的文件,則必須使用 Windows.Storage.Pickers 命名空間中的檔案選擇器來讓使用者選擇檔案 (不啟用對檔案的直接存取)。 另一個範例是,如果某個應用程式想要存取使用者的位置資料,則需要宣告啟用位置裝置功能,在下載時提示使用者該應用程式將請求存取使用者的位置。 最重要的是,當應用程式第一次想要存取使用者的位置時,會向使用者顯示額外的同意提示,請求存取資料的權限。
請注意,此應用程式模型充當應用程式的「監獄」,代表它們無法存取,但它並不是從外部無法存取的「城堡」(具有管理員權限的應用程式當然仍然可以存取)。 Windows 中的 Device Guard 可讓組織/IT 指定允許執行哪些 (Win32) 應用程式,可進一步協助限制此存取。
應用程式模型還管理應用程式生命週期。 例如,它預設限制應用程式的後台執行;一旦應用程式進入後台,進程就會暫停 (在給應用程式一段短暫的時間來解決程式碼中的應用程式暫停問題之後),並且其記憶體也會被凍結。 作業系統確實為應用程式提供了請求特定後台任務執行的機制 (依照計劃,由各種事件觸發,例如互聯網/藍牙連接、電源變化等,以及在特定場景中,例如音樂播放或 GPS 追蹤)。
當裝置上的記憶體資源不足時,Windows 透過終止應用程式來釋放記憶體空間。 此生命週期模型強制應用程式在暫停時保留數據,因為在暫停和終止之間沒有額外的可用時間。
關於詳細資訊,請參閱通用:了解 Windows 10/11 應用程式的生命週期。
4.2 儲存的憑證保護
存取經過驗證的服務的 Windows 應用程式通常會為使用者提供將其憑證儲存在本機裝置上的選項。 這對使用者來說是一個方便; 當他們提供使用者名稱和密碼時,應用程式會在後續啟動應用程式時自動使用它們。 因為如果攻擊者取得此預存數據的存取權,Windows 會提供封裝的應用程式將使用者認證儲存在安全認證保險箱中的能力,因此可能是安全性問題。 應用程式呼叫憑證儲物櫃 API 來儲存和檢索儲物櫃中的憑證,而不是將其儲存在應用程式的儲存容器中。 憑證儲物櫃由作業系統管理,但存取權限僅限於儲存它們的應用程式,從而為憑證儲存提供安全管理的解決方案。
當使用者提供要儲存的憑證時,應用程式會使用 Windows.Security.Credentials 命名空間中的 PasswordVault 物件取得憑證儲物櫃的參考。 然後,它會建立一個包含 Windows 應用程式識別碼以及使用者名稱和密碼的 PasswordCredential 物件。 該資訊將傳遞給 PasswordVault.Add 方法以將憑證儲存在儲物櫃中。 以下 C# 程式碼範例顯示如何完成此操作。
var vault = new PasswordVault();
vault.Add(new PasswordCredential("My App", username, password));
在以下 C# 程式碼範例中,應用程式透過呼叫 PasswordVault 物件的 FindAllByResource 方法來請求與該應用程式對應的所有憑證。 如果傳回多個,它會提示使用者輸入使用者名稱。 如果憑證不在儲物櫃中,應用程式會提示使用者輸入憑證。 然後,使用者使用憑證登入伺服器。
private string resourceName = "My App";
private string defaultUserName;
private void Login()
{
PasswordCredential loginCredential = GetCredentialFromLocker();
if (loginCredential != null)
{
// There is a credential stored in the locker.
// Populate the Password property of the credential
// for automatic login.
loginCredential.RetrievePassword();
}
else
{
// There is no credential stored in the locker.
// Display UI to get user credentials.
loginCredential = GetLoginCredentialUI();
}
// Log the user in.
ServerLogin(loginCredential.UserName, loginCredential.Password);
}
private PasswordCredential GetCredentialFromLocker()
{
PasswordCredential credential = null;
var vault = new PasswordVault();
IReadOnlyList<PasswordCredential> credentialList = null;
try
{
credentialList = vault.FindAllByResource(resourceName);
}
catch(Exception)
{
return null;
}
if (credentialList.Count == 1)
{
credential = credentialList[0];
}
else if (credentialList.Count > 0)
{
// When there are multiple usernames,
// retrieve the default username. If one doesn't
// exist, then display UI to have the user select
// a default username.
defaultUserName = GetDefaultUserNameUI();
credential = vault.Retrieve(resourceName, defaultUserName);
}
return credential;
}
如需詳細資訊,請參閱憑證櫃。
4.3 儲存資料保護
當您處理儲存的資料 (通常稱為靜態資料) 時,對其進行加密可以防止未經授權的使用者存取儲存的資料。 加密資料的兩種常見機制是使用對稱金鑰或使用非對稱金鑰。 然而,資料加密不能確保資料在傳送和儲存期間不會被變更。 換句話說,無法保證資料的完整性。 使用訊息驗證碼、雜湊值和數位簽署是解決此問題的常用技術。
4.3.1 資料加密
使用對稱加密,傳送者和接收者都擁有相同的金鑰,並使用它來加密和解密資料。 這種方法的挑戰是安全地共用金鑰,以便雙方都知道它。
對此的一個答案是非對稱加密,其中使用公鑰/私鑰對。 公鑰可以與任何想要加密訊息的人自由分享。 私鑰始終保密,因此只有您可以使用它來解密資料。 允許發現公鑰的常見技術是使用數位憑證,也簡稱為憑證。 除了有關使用者或伺服器的資訊 (例如名稱、頒發者、電子郵件地址和國家/地區) 之外,憑證還包含有關公鑰的資訊。
Windows 應用程式開發人員可以使用 SymmetricKeyAlgorithmProvider 和 AsymmetricKeyAlgorithmProvider 類別在其 UWP 應用中實現對稱和非對稱加密。 此外,CrypgraphicEngine 類別可用於加密和解密資料、對內容進行簽名以及驗證數位簽署。 應用程式還可以使用 Windows.Security.Cryptography.DataProtection 命名空間中的 DataProtectionProvider 類別來加密和解密儲存的本機資料。
4.3.2 偵測訊息竄改 (MAC、雜湊和簽署)
MAC 是使用對稱金鑰 (稱為秘密金鑰) 或訊息作為 MAC 加密演算法的輸入而產生的程式碼 (或標籤)。 密鑰和演算法在訊息傳輸之前由傳送者和接收者商定。
MAC 會像這樣驗證訊息。
- 傳送者透過使用金鑰作為 MAC 演算法的輸入來匯出 MAC 標籤。
- 傳送者將 MAC 標籤和訊息傳送給接收方。
- 接收方透過使用金鑰和訊息作為 MAC 演算法的輸入來匯出 MAC 標籤。
- 接收方將其 MAC 標籤與傳送者的 MAC 標籤進行比較。 如果它們相同,那麼我們就知道訊息沒有被竄改。
Windows 應用程式可以透過呼叫 MacAlgorithmProvider 類別產生金鑰和 CryptographicEngine 類別來執行 MAC 加密演算法來實現 MAC 訊息驗證。
4.3.3 使用雜湊
雜湊函數是一種加密演算法,它採用任意長的資料塊並傳回稱為雜湊值的固定大小的位元字串。 一整套雜湊函數都可以做到這一點。
在上述訊息傳輸場景中,可以使用雜湊值來取代 MAC。 傳送者傳送雜湊值和訊息,接收方從傳送者的雜湊值和訊息導出自己的雜湊值,並比較兩個雜湊值。 在 Windows 上執行的應用程式可以呼叫 HashAlgorithmProvider 類別,列舉可用的哈希演算法,並執行其中一個。 CryptographicHash 類別表示雜湊值。 CryptographicHash.GetValueAndReset 方法可用於重複雜湊不同的數據,而無需為每次使用重新建立物件。 CryptographicHash 類別的 Append 方法將新資料新增至要進行雜湊處理的緩衝區。 以下 C# 程式碼範例顯示了整個過程。
public void SampleReusableHash()
{
// Create a string that contains the name of the
// hashing algorithm to use.
string strAlgName = HashAlgorithmNames.Sha512;
// Create a HashAlgorithmProvider object.
HashAlgorithmProvider objAlgProv = HashAlgorithmProvider.OpenAlgorithm(strAlgName);
// Create a CryptographicHash object. This object can be reused to continually
// hash new messages.
CryptographicHash objHash = objAlgProv.CreateHash();
// Hash message 1.
string strMsg1 = "This is message 1";
IBuffer buffMsg1 = CryptographicBuffer.ConvertStringToBinary(strMsg1, BinaryStringEncoding.Utf16BE);
objHash.Append(buffMsg1);
IBuffer buffHash1 = objHash.GetValueAndReset();
// Hash message 2.
string strMsg2 = "This is message 2";
IBuffer buffMsg2 = CryptographicBuffer.ConvertStringToBinary(strMsg2, BinaryStringEncoding.Utf16BE);
objHash.Append(buffMsg2);
IBuffer buffHash2 = objHash.GetValueAndReset();
// Convert the hashes to string values (for display);
string strHash1 = CryptographicBuffer.EncodeToBase64String(buffHash1);
string strHash2 = CryptographicBuffer.EncodeToBase64String(buffHash2);
}
4.3.4 數位簽署
數位簽署的儲存訊息的資料完整性以與 MAC 身分驗證類似的方式進行驗證。 這是數位簽署工作流程的運作方式。
- 傳送者透過使用訊息作為雜湊演算法的輸入來導出雜湊值 (也稱為摘要)。
- 傳送者使用其私鑰對摘要進行加密。
- 傳送者傳送訊息、加密摘要以及所使用的雜湊演算法的名稱。
- 接收者使用公鑰來解密其收到的加密摘要。 然後,它使用雜湊演算法對訊息進行雜湊處理以建立自己的摘要。 最後,接收方比較兩個摘要 (收到並解密,及其製作的摘要)。 只有當兩者匹配時,接收方才能確定訊息是由私鑰所有者傳送的,因此他們就是他們所說的人,而且訊息在傳輸過程中沒有被變更。
雜湊演算法非常快,因此即使是大型訊息也可以快速得出雜湊值。 產生的雜湊值是任意長度,並且可以比完整訊息短,因此使用公鑰和私鑰僅加密和解密摘要而不是完整訊息是一種最佳化。
關於更多資訊,請參閱有關數位簽署、MAC、雜湊和簽署以及密碼編譯的文章。
5 摘要
Windows 中的 通用 Windows 平台 提供數種方式來利用作業系統功能來建立更安全的應用程式。 在不同的身分驗證場景中,例如使用 OAuth 身分提供者的單一因素、多因素或代理身分驗證,API 的存在可以緩解最常見的身分驗證挑戰。 Windows Hello 提供了一種新的生物特徵辨識登入系統,可以識別使用者並能主動阻止規避適當識別的嘗試。 也可以提供多層金鑰和憑證,這些金鑰和憑證永遠不會在可信賴平台模組之外顯示或使用。 此外,透過選擇性使用證明身分識別金鑰和憑證,可進一步提供一層安全性。
為了保護傳輸中的資料,API 可以透過 SSL 與遠端系統安全地通訊,同時提供透過 SSL 固定驗證伺服器真實性的可能性。 Azure API 管理透過提供強大的設定選項,使用提供額外混淆 API 端點的代理程式在 Web 上公開 API,從而以受控方式安全地發布 API。 透過使用 API 金鑰來保護對這些 API 的存取,並且可以限制 API 呼叫以控制效能。
當資料到達裝置時,Windows 應用程式模型可以更好地控制應用程式的安裝、更新和存取其資料的方式,同時防止其以未經授權的方式存取其他應用程式的資料。 憑證儲物櫃可以提供由作業系統管理的使用者憑證的安全存儲,並且可以使用通用 Windows 平台提供的加密和哈希 API 來保護裝置上的其他資料。
6 資源
6.1 操作方法文章
- 驗證和使用者識別
- Windows Hello
- 認證保險箱
- Web 驗證代理人
- 指紋生物識別技術
- 智慧卡
- 共用憑證
- 密碼編譯
- 憑證
- 密碼編譯金鑰
- 資料保護
- MAC、雜湊以及簽章
- 密碼編譯的匯出限制
- 常見的密碼編譯工作
6.2 程式碼範例
6.3 API 參考
- Windows.Security.Authentication.OnlineId
- Windows.Security.Authentication.Web
- Windows.Security.Authentication.Web.Core
- Windows.Security.Authentication.Web.Provider
- Windows.Security.Credentials
- Windows.Security.Credentials
- Windows.Security.Credentials.UI
- Windows.Security.Cryptography
- Windows.Security.Cryptography.Certificates
- Windows.Security.Cryptography.Core
- Windows.Security.Cryptography.DataProtection
- Windows.Security.ExchangeActiveSyncProvisioning
- Windows.Security.EnterpriseData