ASP.NET寄發加密加簽信件

在早期ASP.NET 1.0寄發郵件使用System.Web.Mail,在.NET Framework 2.0之後建議改用System.Net.Mail命名空間下的郵件寄發方式,但郵件寄送部分仍不能使用x.509憑證的加密加簽郵件,然而有熱血的開發人員在Open Source的Code Project網站上發表了的信件加簽加密函式庫Cpi.Net.SecureMail library方便寄送S/MIME的郵件

匯入憑證

在ASP.NET中因權限考量,要寄發加簽加密郵件要匯入本機電腦的憑證儲存區裡的我的憑證區,而不直接讀取實體憑證檔案。

  1. 在執行中鍵入mmc 執行「主控台」程式
  2. 在選單中的檔案->新增嵌入式管理單元
  3. 接著新增 [憑證] -> [電腦帳戶] -> [本機電腦]
  4. 在憑證(本機電腦) –> 個人->憑證案燕建選擇匯入
  5. 匯入您的憑證檔案,即完成憑證匯入

2010-08-06_220451

授權憑證的使用權利給 ASP.NET 執行時的那個身份識別

另外因IIS預設是使用網路服務(Network Service)去執行,但是網路服務(Network Service)預設是無法讀取本機電腦裡的憑證,可以改成本機服務(Local Service)方式去執行,不過不建議如此,因本機服務(Local Service)權限太大,所以可能會有安全性的風險,建議只有修改要讀取的憑證給網路服務(Network Service)權限即可,可使用Windows HTTP Services Certificate Configuration Tool (WinHttpCertCfg.exe),下載安裝後,預設會安裝在C:\Program Files\Windows Resource Kits\Tools目錄下,接著到執行CMD指令叫出命令提示列,執行以下指令

cd /d C:\Program Files\Windows Resource Kits\Tools
winhttpcertcfg -g -c LOCAL_MACHINE\MY -s "MyCertificate" -a "Network Service"
其中"MyCertificate"就是你的憑證名稱(Subject Name),而"Network Service"是要授權的帳號。順利執行完畢即能在ASP.NET環境下寄發加密加簽的信件

撰寫程式碼

SecureMailMessage message = new SecureMailMessage();

// 從電腦憑證存放區根據序號取得要加簽使用的憑證
X509Certificate2 signingCert = CryptoHelper.FindCertificate("1B37D3");
// 從電腦憑證存放區根據序號取得要加密使用的憑證 
X509Certificate2 encryptionCert = CryptoHelper.FindCertificate("22C590");

// 從檔案讀取收件者的憑證
X509Certificate2 recipientCert = new X509Certificate2(@"c:\certs\bob.cer");

message.From = new SecureMailAddress
("alice@cynicalpirate.com", "Alice", encryptionCert, signingCert);
message.To.Add(new SecureMailAddress
("bob@cynicalpirate.com", "Bob", recipientCert));

message.Subject = "這是一封加簽加密的郵件";

message.Body = "<h2>這是加簽加密的本文!</h2>";
message.IsBodyHtml = true;

// 是否加簽
message.IsSigned = true;

// 是否加密
message.IsEncrypted = true;

// 仍然可以使用內建的 SMTP Client 幫您寄信

System.Net.Mail.SmtpClient client = 
new System.Net.Mail.SmtpClient("mymailserver", 25);

// 假如 SMTP 需要認證您需要在此指定您的帳號密碼
client.Credentials = new NetworkCredential("YourSmtpUserName", "YourSmtpPassword");

client.Send(message);

補充資料

若使用 Cpi.Net.SecureMail library 提供的 CryptoHelper.FindCertificate 方法讀取憑證,在ASP.NET環境是無法讀取的,因為他是讀取執行者的憑證存放區,建議使用.NET內建的讀取本機電腦裡的我的憑證憑證方式。

public static X509Certificate2 FindCertificate(string serialNumber)
{
X509Store localStore = new X509Store(StoreName.My,StoreLocation.LocalMachine); 
localStore.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); 
try
{
X509Certificate2Collection matches = localStore.Certificates.Find(
X509FindType.FindBySerialNumber,
serialNumber,
true); 
if (matches.Count > 0)
{
return matches[0];
}
else
{
return null;
}
}
finally
{
localStore.Close();
} 
}

留言

這個網誌中的熱門文章

IIS 啟用HTTP Strict Transport Security (HSTS)

解決WCF(REST)在https出現檔案找不到錯誤

Azure Web Apps 讀取憑證