2017-02-13, 2017-05-25, 2020-08-14,2022-06-06更新
續這篇
[研究][C#]加密加簽寄信(使用Cpi.Net.SecureMail)(一)
http://shaurong.blogspot.com/2017/02/ccpinetsecuremail.html
之前是 C# Console 程式,這篇是 ASP.NET 程式
********************************************************************************
********************************************************************************
如果是 Windows 2000 Service Pack 3, Windows Server 2003, Windows XP
因IIS預設是使用網路服務(Network Service)去執行,但是網路服務(Network Service)預設是無法讀取本機電腦裡的憑證,可成本機服務(Local Service)方式去執行,不過不建議如此,因本機服務(Local Service)權限太大,所以可能會有安全性的風險,建議只有修改要讀取的憑證給網路服務(Network Service)權限即可,可使用
Windows HTTP Services Certificate Configuration Tool (WinHttpCertCfg.exe)
2012-08-22
支援 Windows 2000 Service Pack 3, Windows Server 2003, Windows XP
用法
,下載安裝後,x86 MS-Windows 預設會安裝在C:\Program Files\Windows Resource Kits\Tools目錄下,x64 MS-Windows 預設安裝在 C:\Program Files (x86)\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環境下寄發加密加簽的信件。
如果是 Windows Server 2016
如果你在 Windows Server 2016 上照 Windows 2000 Service Pack 3, Windows Server 2003, Windows XP,會出現錯誤
Error: Unable to find or obtain a context for requested certificate
********************************************************************************
Email 憑證每次過期更新,都要重新做一次 (以Windows 2016為例說明)
1.「命令提示字元」下執行mmc,啟動「主控台」
2.在「主控台」,點選「檔案」下拉選單,選「新增/移除嵌入式管理單元」選項
3.「新增或移除嵌入式管理單元」畫面,左邊拉到最下方,選「憑證」,按下中間按鈕「新增」,按下「確定」按鈕
4.「憑證嵌入式管理單元」畫面,預設為「我的使用者帳戶」,改選為「電腦帳戶」,按下「下一步」按鈕
5.「選取電腦」畫面,按下「完成」按鈕
6.「新增或移除嵌入式管理單元」畫面,右邊應該會出現「憑證(本機電腦)」,按下「確定」按鈕
7.在「主控台」,依序樹狀展開「主控台根目錄」、「憑證(本機電腦)」、「個人」、「憑證」,在「憑證」上按下滑鼠右鍵,選「所有工作」,選「匯入」
8.「匯入憑證精靈」畫面,按下「下一步」按鈕
9.檔案總類選全部或 *.pfx,匯入憑證,輸入密碼,憑證存放區選「個人」,把憑證匯入。
10.在「主控台」,依序樹狀展開「主控台根目錄」、「憑證(本機電腦)」、「個人」、「憑證」,在視窗右邊的新匯入憑證上按下滑鼠右鍵,選「所有工作」,選「管理私密金鑰」
11.按下「新增」按鈕,
12.「選取使用者或群組」畫面,按下「進階」按鈕
13.「選取使用者或群組」畫面,按下「立即尋找」按鈕,選取下方IIS_IUSRS,按下「確定」按鈕
14.「選取使用者或群組」畫面,按下「確定」按鈕
15.「XXX 的權限」畫面,勾選「完全控制」和「讀取」
16.完成。
詳細圖解
Windows Server 2016 上可用 "主控台" (MMC) 來處理 Windows HTTP Services Certificate Configuration Tool (WinHttpCertCfg.exe) 要進行的事情。
(下圖)注意,如果是加入 AD 的電腦,請先按「位置」按鈕,選最上方自己的電腦可直接按下「進階」按鈕,選最上方自己的電腦,否則之後找不到 IIS_IUSRS
修改下載得到的 Cpi.Net.SecureMail 方案
修改CryptoHelper.cs 檔案
把 public static X509Certificate2 FindCertificate(string serialNumber) 整個函釋複製一份,修改成下面
public static X509Certificate2 FindCertificate(string serialNumber, StoreLocation storeLocation) { //X509Store localStore = new X509Store(StoreName.My); X509Store localStore = new X509Store(StoreName.My, storeLocation ); 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(); } } |
編譯
Cpi.Net.SecureMail_src\Cpi.Net.SecureMail\bin\Debug 目錄下會有 Cpi.Net.SecureMail.dll 檔案
********************************************************************************
用 Visual Studio 新建立一個 CpiNetSecureMailDemo 方案 (WinForm 程式)
把 Cpi.Net.SecureMail.dll 檔案拷貝到 D:\CodeTemp\CpiNetSecureMailDemo\CpiNetSecureMailDemo\bin 目錄,參考加入 Cpi.Net.SecureMail.dll 檔案
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Defualt.aspx.cs" Inherits="CpiNetSecureMailDemo.Defualt" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> </head> <body> <form id="form1" runat="server"> <div> TO<asp:TextBox ID="TextBox_To" runat="server" Width="500px"></asp:TextBox><br /> CC<asp:TextBox ID="TextBox_CC" runat="server" Width="500px"></asp:TextBox><br /> BCC<asp:TextBox ID="TextBox_BCC" runat="server" Width="500px"></asp:TextBox><br /> Subject<asp:TextBox ID="TextBox_Subject" runat="server" Width="500px"></asp:TextBox><br /> Content<asp:TextBox ID="TextBox_Content" runat="server" Height="100px" TextMode="MultiLine" Width="500px"></asp:TextBox><br /> 附件<asp:FileUpload ID="FileUpload_Attachment" runat="server" /><br /><br /> <asp:Button ID="Button1" runat="server" Text="送出" OnClick="Button1_Click" /> <asp:Label ID="Label_Message" runat="server" Text=""></asp:Label> </div> </form> </body> </html> |
下面黃色字體部分要根據自己情況修改
Default.aspx.cs
using System; using Cpi.Net.SecureMail; using System.IO; using System.Security.Cryptography.X509Certificates; namespace CpiNetSecureMailDemo { public partial class Defualt : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void Button1_Click(object sender, EventArgs e) { try { var message = new SecureMailMessage(); //X509Certificate2 signingCert = new X509Certificate2(@"C:\Certs\MyCert.pfx", "Password123456"); //或 // 使用電腦中儲存的憑證,而非檔案,安全性較高 X509Certificate2 signingCert = CryptoHelper.FindCertificate("3029", StoreLocation.LocalMachine); var from = new SecureMailAddress("testuser1@mail.mymailserver2.com", "XX公司", signingCert, signingCert); message.From = from; if (!string.IsNullOrEmpty(TextBox_To.Text.Trim())) { foreach (var item in TextBox_To.Text.Trim().Split(',', ';')) { var to = new SecureMailAddress(item); message.To.Add(new SecureMailAddress(item)); } } if (!string.IsNullOrEmpty(TextBox_CC.Text.Trim())) { foreach (var item in TextBox_CC.Text.Trim().Split(',', ';')) { message.CC.Add(new SecureMailAddress(item)); } } if (!string.IsNullOrEmpty(TextBox_BCC.Text.Trim())) { foreach (var item in TextBox_BCC.Text.Trim().Split(',', ';')) { message.Bcc.Add(new SecureMailAddress(item)); } } message.Bcc.Add(new SecureMailAddress("testuser1@mail.mymailserver2.com")); message.Subject = TextBox_Subject.Text; message.Body = TextBox_Content.Text; if (FileUpload_Attachment.HasFile) { string filePath = FileUpload_Attachment.PostedFile.FileName; string filename = Path.GetFileName(filePath); Stream fs = FileUpload_Attachment.PostedFile.InputStream; BinaryReader br = new BinaryReader(fs); Byte[] bytes = br.ReadBytes((Int32)fs.Length); MemoryStream destination = new MemoryStream(bytes); message.Attachments.Add(new SecureAttachment(destination, filename)); } message.IsBodyHtml = false; message.IsSigned = true; message.IsEncrypted = false; //System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient(); System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient("smtp.mymailserver2.com", 25); client.Send(message); Label_Message.Text = "已送出郵件"; TextBox_Subject.Text = string.Empty; TextBox_Content.Text = string.Empty; } catch (Exception ex) { Label_Message.Text = ex.Message; } } } } |
即可在 ASP.NET 網頁上寄出加簽 or 加密信件。
PS:好像就算使用外部 SMTP Server,IIS Web Server 本機仍需要有 SMTP Server 才行 (例如:IIS SMTP Server,而且必須開啟 Relay 轉發信件功能才行 ) 。
[研究] IIS SMTP Server 伺服器 安裝 (Windows 2016)
http://shaurong.blogspot.com/2016/10/iis-smtp-server-windows-2016.html
[研究] IIS SMTP Server 伺服器 架設、開放 Relay 轉送 (Windows 2016)
http://shaurong.blogspot.com/2017/05/iis-smtp-server-windows-2016.html
********************************************************************************
2018-06-26
為了避免每次換新憑證要修改內容,可把憑證值放到 Web.Config 中
Web.Config
<configuration> <appSettings> <add key="CertificateSN" value="abcd6b44b617927ecf4b2f32301545ce" /> </appSettings> </configuration> |
Default.aspx.cs
X509Certificate2 signingCert = CryptoHelper.FindCertificate("abcd6b44b617927ecf4b2f32301545ce", StoreLocation.LocalMachine); |
string CertificateSN = Common.ReadSetting("CertificateSN", ""); X509Certificate2 signingCert = CryptoHelper.FindCertificate(CertificateSN, StoreLocation.LocalMachine); |
Common.cs 中增加
public class Common { public static string ReadSetting(string key, string defaultValue) { try { object setting = ConfigurationManager.AppSettings[key]; if (setting != null && setting.ToString().Length == 0) { setting = null; } return (setting == null) ? defaultValue : (String)setting; } catch { return defaultValue; } } } |
(完)
相關
An S/MIME Library for Sending Signed and Encrypted E-mail
Pete Everett, 15 Jul 2010
https://www.codeproject.com/Articles/41727/An-S-MIME-Library-for-Sending-Signed-and-Encrypted
[研究][C#]加密加簽寄信(使用Cpi.Net.SecureMail)(一)
http://shaurong.blogspot.com/2017/02/ccpinetsecuremail.html
[研究][C#]加密加簽寄信(使用Cpi.Net.SecureMail)(二)
http://shaurong.blogspot.com/2017/02/ccpinetsecuremail_13.html
ASP.NET寄發加密加簽信件
https://www.nccst.nat.gov.tw/ArticlesDetail?lang=zh&seq=1160
https://www.codeproject.com/script/Content/ViewAssociatedFile.aspx?rzp=%2FKB%2Fsecurity%2FCPI_NET_SecureMail%2F%2FCpi.Net.SecureMail_src.zip&zep=Cpi.Net.SecureMail_src%2FCpi.Net.SecureMail%2FSecureMailMessage.cs&obid=41727&obtid=2&ovid=5
相關
An S/MIME Library for Sending Signed and Encrypted E-mail
Pete Everett, 15 Jul 2010
https://www.codeproject.com/Articles/41727/An-S-MIME-Library-for-Sending-Signed-and-Encrypted
[研究][C#]加密加簽寄信(使用Cpi.Net.SecureMail)(一)
http://shaurong.blogspot.com/2017/02/ccpinetsecuremail.html
[研究][C#]加密加簽寄信(使用Cpi.Net.SecureMail)(二)
http://shaurong.blogspot.com/2017/02/ccpinetsecuremail_13.html
ASP.NET寄發加密加簽信件
https://www.nccst.nat.gov.tw/ArticlesDetail?lang=zh&seq=1160
https://www.codeproject.com/script/Content/ViewAssociatedFile.aspx?rzp=%2FKB%2Fsecurity%2FCPI_NET_SecureMail%2F%2FCpi.Net.SecureMail_src.zip&zep=Cpi.Net.SecureMail_src%2FCpi.Net.SecureMail%2FSecureMailMessage.cs&obid=41727&obtid=2&ovid=5
沒有留言:
張貼留言