# Microsoft Azure-保護與關鍵的 Azure 保管庫的敏感信息
通過?[Rahul Nath](https://msdn.microsoft.com/zh-cn/magazine/mt149362?author=Rahul+Nath)?| 2015 年 9 月
許多應用程序構建今天處理中的敏感信息某種形式或另一個,通常到外部系統 (如數據庫連接字符串。這些注冊表項通常會將其部署為應用程序的配置文件的一部分并可作為純文本的任何用戶可以訪問部署服務器。很明顯,這會帶來巨大的安全威脅。
Microsoft Azure 密鑰保管庫是云托管硬件安全模塊 (HSM)-備份服務用于管理加密密鑰和其他敏感信息 — 在保管庫密鑰術語中的機密信息 — 在一個中央位置,并且可以通過指定的鍵或機密的相應 URI 訪問通過 REST API。保管庫密鑰還允許您創建的軟件注冊表,而不是 HSM 備份一個;在這兩種情況下該密鑰的私鑰部分不保留鍵保管庫邊界和可以永遠不會被看到或共享。
在本文中,我將向您介紹一家大型公司,Contoso,與外包給不同供應商開發業務線 (LOB) 應用程序構建在其中一個方案。該應用程序與多個第三方服務交互及講述了敏感信息,包括客戶個人身份信息 (PII)。我將介紹如何在現有的實施第一個和安全性會為公司,發出此姿勢然后顯示該公司如何使用 Azure 密鑰保管庫來解決這些問題。
## 現有的應用程序
Contoso 是當前構建 LOB 應用程序對于客戶而言,車輛和其他相關的方到單個平臺上提供連接的汽車體驗對大型的汽車制造公司。由于 Contoso 具有僅小型 IT 團隊內部,它會外包給各種供應商構建的應用程序的不同部分的每個應用程序的開發。該應用程序是云托管,并公開為各種實體的不同 Api 可以與其進行交互。它還使用第三方應用程序 Api 來使用來自外部服務,并調用到內部 Contoso 應用程序通過 Web 服務公開的數據。
應用程序處理 PII,而是保密應安全地存儲。最初,不是真正考慮如何應處理敏感信息,并不同供應商有其自己的方法。連接字符串的大多數都是應用程序配置文件的一部分,使其無法更改每個部署 ;某些密鑰用于加密 PII 信息已硬編碼到應用程序。而某些證書的詳細信息以連接與 Contoso Web 服務是在應用程序的數據庫中。這會變得難以管理對于 Contoso,且公司最后并不建議這樣做與應用程序開發的供應商,共享的敏感信息。Contoso 還認識到任何具有為其部署服務器的訪問權的人都能夠非常輕松地篡改 PII 數據,這樣會嚴重的威脅。該公司強制統一用于維護和訪問敏感信息的方法。
## 應用程序 Refit
Contoso 深入了解了用于管理敏感信息和統一的體驗以便它可以成為一致的跨不同的應用程序的各種備選方法。該公司希望為其安全團隊,可以輕松管理其密鑰的中央存儲,而且它想要為不同應用程序提供不同的訪問策略的信息。此外,Contoso 不希望任何一個過程需要的日常監視具有很大的維護開銷。
于是便選擇了 Azure 密鑰保管庫中,允許使用的軟件和 HSM 備份密鑰,以及從 PFX 文件導入現有密鑰。保管庫密鑰允許您在云中安全地存儲小少量信息 (安全的密碼) 并根據需要訪問它們。因為完全管理此服務并將其保留在 Azure 平臺上,您是從維護它的所有開銷釋放出來。
無法查看或由任何人,使其非常安全的平臺中提取鍵的方式生成保管庫密鑰。它提供一個豐富 API 用于訪問和與保管庫中,以及用于在 Microsoft.NET Framework 運行的應用程序的 C# API 庫進行交互。能夠控制如何不同應用程序和供應商可以與交互如該公司想要限制不同應用程序供應商可以與安全信息進行交互的方式是為 Contoso,一個不錯的選擇使密鑰保管庫的重要因素。另外,Contoso 工程師已經很大程度使用 Windows PowerShell 腳本來管理其各種其他服務器、 和密鑰存儲庫是完全可以通過 Windows PowerShell 進行管理。
創建密鑰的保管庫: Contoso IT 團隊的安全管理員負責設置密鑰保管庫和管理密鑰和機密內容。Azure 密鑰保管庫可以創建和使用 Windows PowerShell cmdlet 管理且可使用最新的 Azure PowerShell (0.9.2 或更高版本)。一旦連接到 Azure 訂閱的 Azure PowerShell 提示符下,您需要切換到 AzureResourceManager 模式,密鑰保管庫 cmdlet 需要。然后,您可以使用新建 AzureKeyVault cmdlet,通過指定保管庫名稱 (這是全局唯一的)、 資源組和位置中創建新的存儲庫:
~~~
Switch-AzureMode AzureResourceManager
New-AzureResourceGroup –Name 'ContosoResourceGroup' –Location 'East Asia'
New-AzureKeyVault -VaultName 'ContosoKeyVault' -ResourceGroupName
? 'ContosoResourceGroup' -Location 'East Asia'
~~~
在成功執行的命令時,新創建的密鑰保管庫的詳細信息被輸出到 Azure PowerShell 控制臺中,其中包括該保管庫名稱和用于唯一標識此保管庫的 URI。
設置鍵保管庫: Azure 密鑰保管庫使創建和存儲加密密鑰,并且還秘密,是具有任何特定語義的有限大小八位位組對象存儲。
支持當前僅 RSA 密鑰和加密密鑰在保管庫中表示為 JSON Web 鍵對象。一旦在保管庫中創建一個鍵后,只有該密鑰的公共部分是在保管庫邊界外可用。
密鑰的保管庫可以包含密鑰和機密,并且可以單獨控制對這些外部訪問。密鑰和機密內容是在保管庫中的受版本控制對象,由保管庫 URL 和對象名稱和其版本號唯一標識一個新。時與現有名稱創建一個對象,創建了一個新對象具有相同的名稱和新的版本號,這將成為最新版本。嘗試訪問沒有版本號的對象返回的當前版本。對象標識符,用于唯一地標識一個保管庫中的某個對象采用以下格式,并使用與密鑰和機密內容使用 API 進行交互:
~~~
https://{keyvault-name}.vault.azure.net/{object-type}/{object-name}/{object-version}
~~~
其中:
~~~
keyvault-name?????????? : Globally unique key vault name
object-type?????????????? : Either "keys" or "secrets," indicating the type of object
object-name????????????? : Unique name within a key vault
object-version?????????? : System generated string, optionally used to ?????????
??????????????????????????? ? identify a specific version of object
~~~
Azure 密鑰保管庫中的鍵與擴展以啟用對 Azure 密鑰保管庫實現是唯一的密鑰類型的基 JWK 規范表示為 JSON Web 鍵 (JWK) 對象。當前 Azure 密鑰保管庫支持僅 RSA 算法,非對稱算法。Azure 保管庫密鑰支持創建、 導入、 更新、 刪除、 列表、 獲取、 備份和還原操作對鍵,并這些操作可使用 REST API 和 Windows PowerShell cmdlet。因為 Contoso 應用程序使用密鑰進行加密和解密特定 PII 的信息,一個密鑰需要在保管庫中創建。Contoso 工程師使用以下腳本將新密鑰添加到保管庫中,與在其保管庫中是唯一的名稱:
~~~
Add-AzureKeyVaultKey -VaultName 'ContosoKeyVault' -Name 'ContosoPIIKey'
? -Destination 'Software'
~~~
在成功執行這將在 ContosoKeyVault,可以使用工程師將共享與應用程序供應商的唯一標識符 (例如,https://ContosoKeyVault.vault.azure.net/keys/ContosoPIIKey/ bfacf5f768ae42ffb0a0bca448aead87) 來標識創建新的軟件 RSA 密鑰。
Azure 密鑰保管庫中的秘密) 是八位字節序列的每個; 25 K 的最大大小接受任何類型的數據并將其安全地存儲。密鑰保管庫支持創建、 獲取、 列表、 刪除和更新的秘密,對操作和這些操作可以使用 REST API 和 Windows PowerShell cmdlet。由于 Contoso 應用程序將連接字符串保存在應用程序配置文件中時,Contoso 工程師可以決定要移到密鑰保管庫,它可以安全地存儲并仍然可以訪問使用唯一標識符。下面的腳本用于將其 SQL 數據庫連接字符串添加到保管庫:
~~~
$ContosoSQLConnectionString = ConvertTo-SecureString -String
? "ContosoSQLConnectionString"
? -AsPlainText -Force
Set-AzureKeyVaultSecret -VaultName "ContosoKeyVault" -Name
? "ContosoSQLConnectionString"
? -SecretValue $ContosoSQLConnectionString
~~~
在成功執行這機密值會在創建 ContosoKeyVault,可以使用的唯一標識符 (如 https://ContosoKeyVault.vault.azure.net/secrets/ContosoSQLConnectionString/ 90018dbb96a84117a0d2847ef8e7189d),其中工程師與應用程序供應商的共享再次進行標識。
進行身份驗證應用程序以使用密鑰保管庫: 新創建的存儲庫是只能從創建它的 Azure 帳戶并不被任何其他用戶目前可以訪問的。Contoso 需求為各種客戶端應用程序訪問到保管庫。使用 Azure Active Directory (Azure AD) 應用程序令牌來保護到 Azure 的關鍵保管庫的訪問。若要執行此操作,Contoso 工程師首先需要在 Azure AD 中創建應用程序使用的身份驗證密鑰 (共享密鑰) 或證書來保護它。可以使用 Azure 管理門戶中,在 Active Directory 選項應用程序選項卡下完成創建 Azure AD 應用程序使用身份驗證密鑰訪問保護。但與身份驗證密鑰保護其密鑰的保管庫不什么 Contoso 傾向于,如下這同樣意味著將敏感信息放在客戶端應用程序配置文件,正是他們想要在第一時間避免。此外,因為鍵保管庫是所有敏感信息的單個存儲區,允許訪問到它的憑據是應極力避免的內容。因此,Contoso 決定使用基于證書的身份驗證,以便它可以將證書部署到需要它的應用程序直接并可以進一步保護使用密碼的證書。
可以通過 Windows PowerShell 命令行創建的 Azure AD 應用程序使用證書身份驗證。Contoso 已有一種機制來生成用于保護其其他內部應用程序,因此該公司使用同一個服務來生成用于 Azure AD 應用程序的證書的證書。一旦該公司擁有該證書,可以使用以下腳本創建 Azure AD 應用程序:
~~~
$certificateFilePath = "C:\certificates\ContosoADApplication.cer"
$x509Certificate2 = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$x509Certificate2.Import($certificateFilePath)
$rawCertData = $x509Certificate2.GetRawCertData()
$credentialValue = [System.Convert]::ToBase64String($rawCertData)
$startDate= [System.DateTime]::Now
$endDate = $startDate.AddYears(1)
$newADApplication = New-AzureADApplication -DisplayName
? "ContosoKeyVaultADApplication"
? -HomePage? "http://www.contoso.com" -IdentifierUris "http://www.contoso.com"?
? -KeyValue? $credentialValue -KeyType "AsymmetricX509Cert" -KeyUsage "Verify"
? -StartDate $startDate -EndDate $endDate
~~~
使用密鑰的保管庫和創建的 Azure AD 應用程序,Contoso 現在已將這些連接在一起以便從 Azure AD 應用程序收到的應用程序令牌可用于對密鑰的保管庫進行身份驗證。這可以通過使用組 AzureKeyVaultAccessPolicy cmdlet。您還設置 Azure AD 應用程序在這一次,對密鑰的保管庫的權限使用 PermissionToKeys 和 PermissionToSecrets 參數。
PermissionToKeys 參數指定要向其授予向應用程序的關鍵操作權限的數組和有一個可接受的值的列表 (解密、 加密、 UnwrapKey、 WrapKey、 驗證、 簽名、 獲取、 列表、 更新、 創建、 導入、 刪除、 備份、 還原所有)。PermissionToSecrets 參數指定要向其授予向應用程序的機密操作權限的數組和也有一個可接受的值的列表 (獲取、 列表、 設置、 刪除、 所有)。權限是適用于所有密鑰和密鑰在保管庫中 ;不允許使用的某些項或保管庫中的機密數據賦予選擇性的權限。如果選擇性訪問密鑰或機密信息的權限是必需的您需要創建與所選的鍵和密鑰來管理的權限的單獨的保管庫。沒有為密鑰保管庫本身,沒有設置費用,但這可能會更改并且想要檢查創建單獨的保管庫之前定價鍵保管庫。若要向不同的訪問級別提供針對相同的密鑰和機密內容,您可以創建多個 Azure AD 應用程序和注冊不同的權限級別。
Contoso 工程師使用以下腳本以將 Azure AD 應用程序和關鍵保管庫中,關聯并指定該應用程序具有在保管庫的權限:
~~~
$ServicePrincipal = New-AzureADServicePrincipal -ApplicationId $newADApplication.ApplicationId
Set-AzureKeyVaultAccessPolicy -VaultName 'ContosoKeyVaultRahul' -ObjectId? $ServicePrincipal.Id
? -PermissionsToKeys encrypt,decrypt,get -PermissionsToSecrets get
$ServicePrincipal.ApplicationId
~~~
從客戶端應用程序連接到保管庫密鑰: 一旦創建 Azure AD 應用程序并將其與鍵的保管庫關聯,您可以使用它從客戶端應用程序進行身份驗證密鑰保管庫。由于 Contoso 應用程序在.NET 平臺上開發的應用程序供應商將使用 Microsoft.Azure.KeyVault NuGet 程序包 ([bit.ly/1Ji6xcS](http://bit.ly/1Ji6xcS)) 連接到關鍵的保管庫。
對與 Azure AD 應用程序的客戶端應用程序進行身份驗證很容易實現使用 Azure AD 身份驗證庫 (ADAL),這也可作為 NuGet 程序包。所有應用程序需要使用 Azure AD 應用程序進行身份驗證是客戶端 ID 和可以放置在配置文件中的證書標識符 (如指紋)。這些可以安全地部署在配置文件中因為本身,它們不是敏感信息。
C# SDK 提供了 KeyVaultClient 類,該類中所示?圖 1。其構造函數采用一個回調方法以提供有效的令牌從 Azure AD 應用程序。每當使用客戶端執行加密操作時調用回調方法。有效的證書是使用自定義的函數 GetCertificateByThumbprint,從應用程序的配置文件中使用的指紋信息和用于對 Azure AD 應用程序進行身份驗證獲取的。ADAL 庫緩存從 Azure AD 應用程序第一次收到的令牌和令牌過期之前提供從為每個后續調用緩存的令牌。
圖 1 連接到關鍵的保管庫
~~~
var keyVaultClient = new KeyVaultClient(async (authority, resource, scope) =>
{???????????????
? string azureAdApplicationId =
???? ConfigurationManager.AppSettings["AzureAdApplicationId"];
? string certificateThumbprint =
??? ConfigurationManager.AppSettings["CertificateThumbprint"];
? X509Certificate2 certificate =
??? GetCertificateByThumbprint(certificateThumbprint);
? var clientAssertionCertificate =
??? new ClientAssertionCertificate(azureAdApplicationId, certificate);
? var authenticationContext = new AuthenticationContext(authority);
? var result =
??? await authenticationContext.AcquireTokenAsync(resource,??
??? clientAssertionCertificate);
? return result.AccessToken;
});
~~~
配置客戶端應用程序以使用密鑰和機密內容: 客戶端應用程序供應商現在需要更新現有的應用程序以使用的鍵和 Contoso 工程師由共享機密標識符從保管庫中獲取所需的連接字符串和密鑰信息。由于本身的密鑰標識符不是敏感信息,可以安全地將它們放在應用程序的配置文件中。
在連接字符串或已保存為一個秘密密鑰的保管庫中的類似敏感信息是必需的被替換現有代碼從保管庫使用 KeyVaultClient 讀取:
~~~
var connectionStringIdentifier =
? ConfigurationManager.AppSettings["ConnectionStringIdentifier"];
var contosoSQLConnectionString =
? await keyVaultClient.GetSecretAsync(connectionStringIdentifier);
~~~
首先,此代碼查找的連接字符串機密標識符存儲在配置文件并使用此 SDK 客戶端檢索密鑰值,在這種情況下是一個連接字符串。連接字符串然后可根據需要連接到應用程序數據庫。
該應用程序須加密或解密 PII 信息的現有代碼替換為代碼以執行該操作使用 SDK 客戶端并指定要使用的密鑰標識符。下面的代碼演示如何加密并隨后會解密回原始文本一些文本:
~~~
// Within the actual application, encryption and decryption
// would happen at different parts.
var contosoPIIKeyIdentifier =
? ConfigurationManager.AppSettings["ContosoPIIKeyIdentifier"];
Byte[] textToEncrypt = Encoding.Unicode.GetBytes("Consumer PII Information");
var encryptedResult =
? await keyVaultClient.EncryptAsync(contosoPIIKeyIdentifier, "RSA_OAEP",? textToEncrypt);
var decryptedResult =
? await keyVaultClient.DecryptAsync(contosoPIIKeyIdentifier,
? "RSA_OAEP", encryptedResult.Result);
var text = Encoding.Unicode.GetString(decryptedResult.Result);
~~~
維護關鍵保管庫: Contoso 工程師負責維護的生存期內,其中包括更改與密鑰標識符中 ; 相關聯的密鑰值的鍵的保管庫更新為機密的標識符 ; 相關聯的密鑰值創建新的密鑰或密鑰的值 ;正在更新等用于 Azure AD 應用程序身份驗證的證書。
若要創建或更新密鑰和機密內容的保管庫中,使用如前面的腳本。在為一個秘密或密鑰指定的對象標識符不存在的保管庫中,都會創建一個新的對象。有關現有標識符,保管庫會自動創建的新版本并成為最新版本。較舊的值將保留在保管庫并可供引用的標識符名稱和在 URI 中的版本號。客戶端應用程序可以決定是否在根據其需求的標識符中包含的版本號。對于不同的應用程序版本,你可以任選一個來在同一個保管庫中,具有不同保管庫或具有不同名稱的標識符或標識符具有相同名稱但具有在標識符 URI 中顯式指定版本號。Contoso 安全策略要求密鑰,如連接字符串和為其工程師請按照下面的工作流的證書的密鑰值的頻繁的更改 (滾動):
* 當保管庫中存儲的密鑰都更新到較新版本時,將使用這些密鑰加密的數據存儲的客戶端應用程序將需要確保加密的數據都將遷移為使用新密鑰。
* Contoso 客戶端應用程序維護所使用的數據進行加密的密鑰版本并始終使用的解密相同的數據時。
* 加密數據時,應用程序始終將使用新密鑰的信息。這允許應用程序逐漸將遷移到新的密鑰值,以及它們創建時。
對于更新密鑰值,該過程取決于密鑰表示的值的種類。對于提供信息,如連接字符串的值,您首先切換到備用服務的密鑰的值,然后前滾主服務的憑據信息和更新密鑰與主服務已更新的憑據。對于某些服務如 Azure 存儲,這是更簡單,因為有一些主要和輔助密鑰可互換使用時或者正在更新。對于其值僅與該應用程序的機密內容,機密是直接更新以便反映的任何新值。
證書用于保護 Azure AD 應用程序需要進行更改,Contoso 工程師使用 Windows PowerShell 腳本以執行更新。若要更新 Azure AD 應用程序的證書,需要安裝 Azure AD 模塊。您會發現模塊在[bit.ly/1OdZTIS](http://bit.ly/1OdZTIS)。Contoso 工程師然后使用在該腳本?圖 2?以上載新證書來保護 Azure AD 應用程序。
圖 2 用于上載新證書的 Azure PowerShell 腳本
~~~
$certificateFilePath = "C:\certificates\ContosoADApplicationNew.cer"
$x509Certificate2 =
? New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$x509Certificate2.Import($certificateFilePath)
$rawCertData = $x509Certificate2.GetRawCertData()
$credentialValue = [System.Convert]::ToBase64String($rawCertData)
$startDate= [System.DateTime]::Now
$endDate = $startDate.AddYears(1)
$msolCredentials = get-credential
connect-msolservice -credential $msolCredentials
New-MsolServicePrincipalCredential -ServicePrincipalName $ServicePrincipal.ApplicationId
? -Type Asymmetric -Value $credentialValue -StartDate $startDate -EndDate $endDate
~~~
當任何應用程序不再使用的證書憑據時,Contoso 工程師將運行以下腳本以從使用 Get-msolserviceprincipalcredential cmdlet 來獲取需要刪除的憑據的標識符的服務主體中刪除憑據密鑰:
~~~
$servicePrincipalCredential = Get-MsolServicePrincipalCredential
? -ServicePrincipalName $ServicePrincipal.ApplicationId -ReturnKeyValues 0
Remove-MsolServicePrincipalCredential
? -ServicePrincipalName $ServicePrincipal.ApplicationId
? -KeyIds $servicePrincipalCredential[0].KeyId
~~~
此腳本只需通過只從列表中刪除第一個憑據顯示 cmdlet 的用法。在實際的應用程序可能顯式聲明要刪除的證書憑據的標識符。
處理多個部署: 該應用程序當前只依賴于 Azure AD 應用程序 ID,用于標識要使用 Azure AD 應用程序,以及各種密鑰和機密標識符進行身份驗證的證書的證書指紋。對于應用程序的不同部署,可以使用不同的密鑰保管庫。對于開發人員部署每個應用程序供應商可以創建密鑰的保管庫使用的操作的步驟,我討論了 ; 其 Azure 訂閱設置保管庫并填充的密鑰和機密該應用程序需要;然后更新配置文件。當 Contoso 團隊需要部署用于測試應用程序時,它們可以使用從保管庫在其訂閱下部署的詳細信息更新配置文件。
## 總結
Contoso 是高興有實現這一轉換到 Azure 密鑰保管庫,這可以幫助公司能夠輕松地處理其應用程序必須向其應用這些安全風險的大多數。它已能夠完成所有內容都將其設置出處理很少調整到應用程序代碼中,并且這也使得很輕松地管理各種類型的敏感信息。Contoso 是能夠進行此開關的易用性鼓勵公司還使它們更加安全地重新訪問其其他 LOB 應用程序。Azure 密鑰保管庫是大部分應用程序可能會使利用右離開,并使存儲和管理加密密鑰和其他敏感信息輕松、 安全。
* * *
Rahul Nath?*是開發人員、 顧問和博主具有從構建豐富的 windows Azure 平臺上的大型應用程序的客戶端應用程序的體驗。您可以關注他的 Twitter (網址?[twitter.com/rahulpnath](http://twitter.com/rahulpnath)?或閱讀他的博客[rahulpnath.com](http://rahulpnath.com/)。*
- 介紹
- 云連接移動應用 - 借助身份驗證和離線支持構建 Xamarin 應用
- 崛起 - 自由 Internet 廣播
- Microsoft Azure - 云中的容錯問題和解決方法
- 最前沿 - 適合常見應用程序的事件源
- Azure 深入了解 - 跨云平臺創建統一的 Heroku 式工作流
- 借助 C++ 進行 Windows 開發 - Windows 運行時中的高級類型
- 編譯器優化 - 借助按本機配置優化來簡化代碼
- 數據點 - 再探 JavaScript 數據綁定(現在包含 Aurelia)
- 云安全 - 借助 Azure 密鑰保管庫保護敏感信息的安全
- 測試運行 - 借助人工尖峰神經元進行計算
- 開發運營 - 在 Microsoft 堆棧上啟用開發運營
- 孜孜不倦的程序員 - 如何成為 MEAN: Node.js
- 新型應用 - 提升新型應用的易用性的做法
- 別讓我打開話匣子 - Darwin 的照相機
- 編輯寄語 - 汽車 Internet 發生故障