標籤:style http io color ar os 使用 sp for
.NET為我們提供了運算元字認證的兩個主要的類,分為為:
System.Security.Cryptography.X509Certificates.X509Certificate2類, 每個這個類的執行個體可以表示一個認證;
System.Security.Cryptography.X509Certificates.X509Store類,可以對儲存在電腦安全區域內的認證進行add/remove/get操作。
另外我們可以使用System.Security.Cryptography.X509Certificates.X509Certificate2UI類來顯示認證訊息的對話方塊,它就是在IE中的認證查看器的.NE實現。
產生認證
在介紹以上類的使用方法之前,我們先要擁有一個數位憑證,擷取數位憑證有三種方法,一是從CA機構申請,二是自己搭建伺服器發布認證,三是使用makecert.exe來產生一個認證檔案。這裡我們使用makecert.exe來產生一個認證檔案,用來測試。啟動VS2010的命令列,輸入對應參數,產生名為TestCertificates的認證檔案。6-28所示。
圖6-28 產生認證
makecert.exe的參數讀者可以查看協助,這裡只解釋圖6-28中的參數。
參數說明:
-sr CurrentUser:指定主題的憑證存放區位置。Location 可以是 currentuser(預設值)或 localmachine
-ss MyTestContainer:指定主題的憑證存放區名稱,輸出認證即儲存在那裡。
-n CN=TestCert:指定主題的認證名稱。此名稱必須符合 X.500 標準。最簡單的方法是在雙引號中指定此名稱,並加上首碼 CN=;例如,"CN=myName"。
-sky exchange:指定頒發者的密鑰類型,必須是 signature、exchange 或一個表示提供者類型的整數。預設情況下,可傳入 1 表示交換密鑰,傳入 2 表示簽名密鑰。
-pe:將所產生的私密金鑰標記為可匯出。這樣可將私密金鑰包括在認證中。
產生的密鑰檔案被儲存在了我們指定的MyTestContainer中,但到哪去查看我們的認證呢?Windows沒有給我們準備好直接的管理憑證的入口,但我們可以在MMC控制台自行添加。
- 開始 ? 運行 ? MMC,開啟一個空的MMC控制台。
- 在控制台菜單,檔案 ? 添加/刪除嵌入式管理單元 ? 添加按鈕 ? 選"認證" ? 添加 ? 選"我的使用者賬戶" ? 關閉 ? 確定
- 在控制台菜單,檔案 ? 添加/刪除嵌入式管理單元 ? 添加按鈕 ? 選"認證" ? 添加 ? 選"電腦賬戶" ? 關閉 ? 確定
6-29,我們可以查看兩個賬戶的認證管理,在我的賬戶中可以看到MyTestContainer下的認證TestCert。
圖6-29 在MMC控制台查看和管理憑證
當然我們也可以將認證檔案儲存為檔案,6-30所示。
圖6-30 將認證儲存為檔案
開啟E盤,可以看到產生的認證檔案。6-31所示。
圖6-31 產生的認證檔案
將認證儲存為檔案時,我們有三種選擇:
- 帶有私密金鑰的認證
由Public Key Cryptography Standards #12,PKCS#12標準定義,包含了公開金鑰和私密金鑰的二進位格式的認證形式,以pfx作為認證檔案尾碼名。
- 二進位編碼的認證
認證中沒有私密金鑰,DER 編碼二進位格式的認證檔案,以cer作為認證檔案尾碼名。
- Base64編碼的認證
認證中沒有私密金鑰,BASE64 編碼格式的認證檔案,也是以cer作為認證檔案尾碼名。
按右鍵本地的認證檔案,我們可以看到安裝選項,可以把該認證檔案安裝到憑證存放區區。也可在MMC的認證管理台上執行匯出任務將儲存區的認證匯出為檔案。這裡就不再示範了,讀者可以自行實踐。
編程操作認證
我們可以通過編程的方式操作操作本地的認證檔案和在儲存區中的認證。我們以剛才儲存在E盤的test.cer檔案為例,講解如何讀取本地的認證檔案,並將它添加到儲存區中。先看代碼清單6-17。
代碼清單 6-17 操作本地認證檔案
- class OperCert
- {
- internal static byte[] ReadFile(string fileName)
- {
- FileStream f = new FileStream(fileName, FileMode.Open, FileAccess.Read);
- int size = (int)f.Length;
- byte[] data = new byte[size];
- size = f.Read(data, 0, size);
- f.Close();
- return data;
- }
- static void Main(string[] args)
- {
- try
- {
- X509Certificate2 x509 = new X509Certificate2();
- byte[] rawData = ReadFile(@"e:\test.cer");
- x509.Import(rawData);
- Console.WriteLine("{0}Subject: {1}{0}", Environment.NewLine, x509.Subject);
- Console.WriteLine("{0}Issuer: {1}{0}", Environment.NewLine, x509.Issuer);
- Console.WriteLine("{0}Version: {1}{0}", Environment.NewLine, x509.Version);
- Console.WriteLine("{0}Valid Date: {1}{0}", Environment.NewLine, x509.NotBefore);
- Console.WriteLine("{0}Expiry Date: {1}{0}", Environment.NewLine, x509.NotAfter);
- Console.WriteLine("{0}Thumbprint: {1}{0}", Environment.NewLine, x509.Thumbprint);
- Console.WriteLine("{0}Serial Number: {1}{0}", Environment.NewLine, x509.SerialNumber);
- Console.WriteLine("{0}Friendly Name: {1}{0}", Environment.NewLine, x509.PublicKey.Oid.FriendlyName);
- Console.WriteLine("{0}Public Key Format: {1}{0}", Environment.NewLine, x509.PublicKey.EncodedKeyValue.Format(true));
- Console.WriteLine("{0}Raw Data Length: {1}{0}", Environment.NewLine, x509.RawData.Length);
- Console.WriteLine("{0}Certificate to string: {1}{0}", Environment.NewLine, x509.ToString(true));
- Console.WriteLine("{0}Certificate to XML String: {1}{0}", Environment.NewLine, x509.PublicKey.Key.ToXmlString(false));
- X509Store store = new X509Store();
- store.Open(OpenFlags.MaxAllowed);
- store.Add(x509);
- store.Close();
- }
- catch (Exception e)
- {
- Console.WriteLine("Error:"+e.Message);
- }
- }
- }
代碼清單6-17示範了如何讀取本地認證檔案的方法。靜態方法ReadFile用來從本地磁碟中讀取認證檔案到byte數組中。主要的操作都在Main方法中。X509Certificate2 x509 = new X509Certificate2()一句使用無參數的建構函式初始化X509Certificate2類的執行個體x509。然後我們使用x509.Import(rawData)語句將byte數組匯入到當前認證執行個體。接下來是輸出該認證的資訊。
輸出資訊之後,我們看下面的四行代碼:
- X509Store store = new X509Store();
- store.Open(OpenFlags.MaxAllowed);
- store.Add(x509);
- store.Close();
首先我們初始化一個X509Store類的執行個體store,然後使用Open方法開啟儲存區,添加上面讀取的認證到儲存區。
X509Certificate2一共提供了14個建構函式供我們使用,這裡就不一一介紹了。我們也可以通過X509Certificate2類的建構函式直接匯入本地的認證檔案,可以使用代碼清單6-18所示的方式。
代碼清單6-18 使用建構函式匯入認證檔案
- X509Certificate2 myX509Certificate2 = new X509Certificate2(
- @"e:\MyTestCert.pfx", //憑證路徑
- "password", //認證的私密金鑰保護密碼
- X509KeyStorageFlags.Exportable //表示此認證的私密金鑰以後還可以匯出
- );
代碼清單6-18給出了如何匯入帶私密金鑰保護密碼的認證的方法。X509KeyStorageFlags 枚舉用來標識X.509 憑證的私密金鑰匯出到何處以及如何匯出。該枚舉的成員說明如表6-1所示。
表6-1 X509KeyStorageFlags 枚舉說明
成員名稱 |
說明 |
DefaultKeySet |
使用預設的密鑰集。使用者密鑰集通常為預設值。 |
UserKeySet |
私密金鑰儲存在目前使用者儲存區而不是本機電腦儲存區。既使認證指定密鑰應儲存在本機電腦儲存區,私密金鑰也會儲存到目前使用者儲存區。 |
MachineKeySet |
私密金鑰儲存在本機電腦儲存區而不是目前使用者儲存區。 |
Exportable |
匯入的密鑰被標記為可匯出。 |
UserProtected |
通過對話方塊或其他方法,通知使用者密鑰被訪問。使用的密碼編譯服務提供者 (CSP) 定義確切的行為。 |
PersistKeySet |
匯入認證時會儲存與 PFX 檔案關聯的密鑰。 |
那麼如何操作儲存區中的認證呢,可以使用代碼清單6-19的方式。
代碼清單6-19 操作儲存區中的認證
- X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
- store.Open(OpenFlags.ReadOnly);
- //輪詢儲存區中的所有認證
- foreach(X509Certificate2 myX509Certificate2 in store.Certificates)
- {
- //將認證的名稱跟要匯出的認證MyTestCert比較,找到要匯出的認證
- if (myX509Certificate2.Subject == "CN=TestCert")
- {
- //認證匯出到byte[]中,password為私密金鑰保護密碼
- byte[] CertByte = myX509Certificate2.Export(X509ContentType.Pfx,"password");
- //將認證的位元組流寫入到認證檔案
- FileStream fStream = new FileStream(
- @"C:\Samples\PartnerAEncryptMsg\MyTestCert_Exp.pfx",
- FileMode.Create,
- FileAccess.Write);
- fStream.Write(CertByte, 0, CertByte.Length);
- fStream.Close();
- }
- }
- store.Close();
代碼清單6-19首先聲明X509Store類的執行個體store,使用了兩個參數的建構函式,第一個參數是儲存容器的名稱,StoreName枚舉只能枚舉系統預設的儲存區名稱。第二個參數是StoreLocation枚舉,用來標識是本機認證還是目前使用者認證。匯出容器認證使用的是Export方法。第一個參數X509ContentType.Pfx表示要匯出為含有私密金鑰的pfx認證形式,第二個參數為私密金鑰保護密碼。如果要匯出為不含私密金鑰的cer認證,第一個參數使用X509ContentType.Cert,表示匯出為不含私密金鑰的cer認證,也就不要求輸入密碼了。
建立發行者認證
發行者認證是驗證發行者可靠性的認證檔案,保護認證發行者的簽名。我們可以從憑證授權單位獲得該檔案。做為程式測試,我們可以使用Cert2spc.exe來產生發行者認證。從命令列啟動該程式,6-32所示。
圖6-32 產生SPC檔案
6-32,我們使用Cert2spc.exe以test.cer為參數產生目標為tset.spc的發行者認證,如果存在多個認證檔案,可以作為參數以空格隔開產生統一的發行者認證。
使用認證對檔案簽名
簽名工具 (SignTool.exe) 是一個命令列工具,用於對檔案進行數位簽章,驗證檔案或時間戳記檔案中的簽名。我們可以對cab檔案、dll檔案或者其他檔案進行簽名,從互連網訪問這些檔案的時候就需要安裝和驗證認證。該工具詳細的說明讀者可以從MSDN上找到,我就不在重複了。
NET中如何運算元字認證詳解