首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

.NET 安全實戰:.NET Framework 2.0 憑證完整應用指南

     編輯:關於.NET

.NET Framework 2.0 大幅強化憑證支援,新增 System.Security.Cryptography.X509Certificates 命名空間與 X509Certificate2 類別,提供符合 PKCS #7/CMS 標準的加密簽名 API。本文系統涵蓋:Windows 憑證存儲區操作、憑證類別體系、驗證/SSL/Web 服務/程式碼簽名應用、資料簽名加密與解密驗證完整流程。

一、憑證基礎與取得途徑

  • 格式:X.509 v3 (RFC 3280),ASN.1 編碼,含公開金鑰、主體資訊、有效期、簽發者簽名。
  • 金鑰演算法:RSA 為最普遍非對稱加密。
  • 檔案格式:.cer (公開金鑰)、.pfx (含私鑰,PKCS #12,可設密碼保護)。
  • 取得來源:商業 CA (公開信任)、企業內部 CA (AD 整合)、makecert.exe (測試)、selfssl.exe (IIS SSL 快速建立)。

二、Windows 憑證存儲區

  • 使用者存儲區:位於使用者設定檔,ACL 保護。容器:Personal (我的憑證)、Trusted Root CA、Other People 等。工具:certmgr.msc。
  • 電腦存儲區:機器層級,供 NETWORK/LOCAL SYSTEM/ASP.NET 使用。管理需 MMC +「憑證」嵌入式管理單元選擇「電腦帳戶」。
  • 私鑰 ACL 問題:ASP.NET 存取電腦存儲區私鑰需調整金鑰容器檔案 ACL (工具見文末連結)。

三、.NET 憑證類別體系

類別特點
X509Certificate1.x 版本,功能有限,不支援加密操作。
X509Certificate22.0 新增,繼承自前者,支援私鑰操作、PKCS#7、完整屬性存取。**首選類別**。

兩者可互轉,但建議統一使用 X509Certificate2。

四、核心 API 操作範例

1. 載入憑證

// 從 .cer
X509Certificate2 cert1 = new X509Certificate2("alice.cer");

// 從 .pfx (需 SecureString 密碼)
SecureString pwd = GetSecureStringFromConsole(); // 禁用回顯讀取
X509Certificate2 cert2 = new X509Certificate2("alice.pfx", pwd);

2. 存取存儲區


X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser); // Personal = My
store.Open(OpenFlags.ReadOnly);
var col = store.Certificates.Find(X509FindType.FindBySubjectKeyIdentifier, "21f2bf44...", true);
X509Certificate2 cert = col[0];
store.Close();
常用搜尋條件:主體名稱、序號、指紋 (SHA-1,換發會變)、主體金鑰識別碼 (SKI,較穩定)。

3. UI 對話框


// 選擇憑證
X509Certificate2 cert = X509Certificate2UI.SelectFromCollection(store.Certificates, "標題", "訊息", X509SelectionFlag.SingleSelection)[0];
// 顯示詳細資訊
X509Certificate2UI.DisplayCertificate(cert);

4. 憑證驗證鏈


X509Chain chain = new X509Chain();
chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
chain.ChainPolicy.RevocationMode = X509RevocationMode.Online | X509RevocationMode.Offline;
chain.ChainPolicy.UrlRetrievalTimeout = TimeSpan.FromSeconds(30);
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
// chain.ChainPolicy.VerificationTime = new DateTime(1999,1,1); // 歷史時間點驗證
chain.Build(cert);
if (chain.ChainStatus.Length > 0) Console.WriteLine(chain.ChainStatus[0].Status);

五、應用場景整合

1. SSL / HTTPS

  • HttpWebRequest / Web 服務 Proxy:URL 使用 https:// 自動啟用。
  • 伺服器憑證驗證失敗預設中斷,可覆寫 ServicePointManager.ServerCertificateValidationCallback 自訂策略 (如測試環境允許過期)。
  • 用戶端憑證驗證:request.ClientCertificates.Add(cert)。
  • SslStream:為任意 Stream 加上 SSL 層,支援自訂驗證回調,適用非 HTTP 協定。

2. Web 服務安全 (WS-Security)

  • WSE 3.0:X509SecurityToken 加入 RequestSoapContext.Security.Tokens。
  • WCF:組態檔 <serviceCredentials> 宣告存儲區位置、名稱、搜尋類型與值,完全對應程式碼枚舉。

3. 程式碼簽名與安全性原則

  • signtool.exe 簽署 .exe/.dll (Authenticode),驗證發布者身分。
  • 強名稱簽名優先於 Authenticode;簽名可能增加啟動延遲。
  • 軟體限制原則:依簽名限制非託管程式執行。
  • CAS 原則:依發行者憑證建立程式碼群組授權權限集。
  • ClickOnce:部署/應用程式資訊清單簽名,安裝時呈現發布者資訊與信任提示。

六、資料簽名與加密 (PKCS #7 / CMS)

核心類別:ContentInfo (資料封裝)、SignedCms (簽名)、EnvelopedCms (加密)、CmsSigner/CmsRecipient。

流程:先簽名後加密


// 1. 簽名
byte[] Sign(byte[] data, X509Certificate2 signerCert) {
    ContentInfo content = new ContentInfo(data);
    SignedCms signed = new SignedCms(content);
    signed.ComputeSignature(new CmsSigner(signerCert));
    return signed.Encode(); // 含資料、簽名、簽名憑證
}

// 分離簽名 (不含資料,適合大量小資料)
SignedCms signed = new SignedCms(content, true); // true = detached
// ... 同樣 ComputeSignature
return signed.Encode(); // 僅含簽名

// 2. 加密
byte[] Encrypt(byte[] data, X509Certificate2 recipientCert) {
    ContentInfo content = new ContentInfo(data);
    EnvelopedCms env = new EnvelopedCms(content);
    env.Encrypt(new CmsRecipient(recipientCert)); // 產生隨機 Session Key 對稱加密資料,再用接收者公開鑰加密 Session Key
    return env.Encode();
}

接收端:先解密後驗證


// 解密
EnvelopedCms env = new EnvelopedCms();
env.Decode(encryptedData);
env.Decrypt(); // 自動從存儲區尋找私鑰解密 Session Key
byte[] plain = env.ContentInfo.Content;

// 驗證簽名 (含憑證鏈驗證)
SignedCms signed = new SignedCms();
signed.Decode(signedData); // 或分離簽名需先載入資料再 Decode(signature)
signed.CheckSignature(false); // false = 驗證簽名+憑證
// 取得簽名者資訊
foreach (SignerInfo si in signed.SignerInfos) Console.WriteLine(si.Certificate.Subject);
byte[] original = signed.ContentInfo.Content;

分離簽名驗證:new SignedCms(content, true).Decode(signature).CheckSignature(false)。

七、原始碼下載

包含 Windows Forms 範例應用程式,示範憑證選擇、檔案簽名加密、驗證解密完整流程:
本文配套原始碼

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved