2019-09-30
2020-01-16 更新 Server.MapPath 問題
2022-06-06 Email憑證建議改用憑證序號抓
********************************************************************************
相關3篇
[研究][C#][ASP.NET] 加簽寄信 (使用 MailKit 和 MimeKit)
https://shaurong.blogspot.com/2019/10/caspnet-mailkit-mimekit_13.html
[研究][C#][ASP.NET] 寄信 (使用 MailKit 和 MimeKit)
https://shaurong.blogspot.com/2019/10/caspnet-mailkit-mimekit_11.html
[研究][C#][ASP.NET] 加簽寄信 (使用 System.Net.Mail.MailMessage)
https://shaurong.blogspot.com/2019/10/caspnet-systemnetmailmailmessage.html
********************************************************************************
本篇不需要用到 Cpi.Net.SecureMail,就可以寄加簽 ( signed mail ) 信件。
加密信 (encrypted mail ) 有待研究。
綠色的部分依據自己情況換掉。
NuGet 要安裝 System.Security.Cryptography.Pkcs
Email 憑證匯入本機憑證儲存區 ,請看下面這篇
[研究][C#]加密加簽寄信(使用Cpi.Net.SecureMail)(二)
http://shaurong.blogspot.com/2017/02/ccpinetsecuremail_13.html
憑證名稱請看下圖
********************************************************************************
以 Windows Server 2019 IIS SMTP 當 localhost port 25 寄信測試。
收件者是 MAIL2000 信箱可以收到信。
收件者是 Gmail 信箱收不到到信。(畢竟 IIS SMTP 不是正式有 FQDN 的 Mail Server )
收件者是公司信箱不一定,若在公司測試,可以收到信;家中電腦測試,收不到。(可能驗證來源 IP 是否公司使用的 IP )
收件者是 "十分鐘信箱",可以收到信。
Web.Config 部分
<?xml version="1.0" encoding="utf-8"?> <configuration> <appSettings> <add key="EmailCertificateSN" value="郵件憑證序號" /> </appSettings> </configuration> |
WebApplication1.aspx.cs
using System; using System.IO; using System.Net.Mail; using System.Security.Cryptography.Pkcs; using System.Security.Cryptography.X509Certificates; using System.Text; //1. 先在專案中加入組件參考:System.Security //2. 設定 using 以下兩個命名空間 System.Security 和 System.Net.Mail.MailMessage using System.Security; //using MailMessage = System.Web.Mail.MailMessage; ///過時 using MailMessage = System.Net.Mail.MailMessage; using System.Net; namespace WebApplication1 { public partial class Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void Button1_Click(object sender, EventArgs e) { //3.郵件內容 string emailContent = "Email Content"; StringBuilder sb = new StringBuilder(); sb.AppendLine("Content-Type: text/html; charset=\"big5\""); sb.AppendLine("Content-Transfer-Encoding: 8bit"); sb.AppendLine(); sb.AppendLine(emailContent.ToString()); byte[] data = Encoding.GetEncoding("Big5").GetBytes(sb.ToString()); // 4.替郵件內容做簽章(重點程式) // 方法1 (更換憑證方便,但密碼顯示程式中 ) // 如果是寫在 Class1.cs 等類別程式中,HttpContext.Current 不可省略 // string pfxPath = HttpContext.Current.Server.MapPath("/App_Data/TestEmailCert.pfx"); //string pfxPassword = "test"; //X509Certificate2 certificate = new X509Certificate2(pfxPath, pfxPassword); //ContentInfo content = new ContentInfo(data); //SignedCms signedCms = new SignedCms(content, false); //CmsSigner signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, certificate); //signedCms.ComputeSignature(signer); //byte[] signedbytes = signedCms.Encode(); // 4方法 2 (憑證必須先匯入本機憑證儲存區,手續麻煩,但密碼不顯示程式中 ) X509Store store = new X509Store("My", StoreLocation.LocalMachine); store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); // //「憑證名稱」為「mmc / 憑證(本機電腦) / 個人 / 憑證」右邊視窗的「發給」欄位顯示的名稱。如果新舊憑證都尚未過期,會抓到舊的憑證 // X509Certificate2 signCert = store .Certificates.Find(X509FindType.FindBySubjectName, "憑證名稱", false)[0]; // 用郵件憑證序號抓 X509Certificate2 signCert = store.Certificates.Find(X509FindType.FindBySerialNumber, emailCertificateSN, false)[0]; setting = ConfigurationManager.AppSettings["EmailCertificateSN"]; string emailCertificateSN = setting.ToString(); SignedCms signedCms = new SignedCms(new ContentInfo(data), false); CmsSigner signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, signCert); signedCms.ComputeSignature(signer); byte[] signedbytes = signedCms.Encode(); //5.郵件內容 MailMessage msg = new MailMessage(); msg.From = new MailAddress("from@example.com"); msg.To.Add(new MailAddress("to@example.com")); msg.Subject = "test s/mime"; // 千萬不要加上 msg.Body 內容,否則驗證 S/MIME 郵件時會失敗 // msg.Body = EmailBody; ///6.將簽章內容加入到訊息的另一個 View 中( AlternateView ),可以「讀取 S/ MIME 郵件」的人可開啟 S/ MIME 郵件檢視,無法讀取「S/ MIME 郵件」的人也可以看到郵件。 MemoryStream ms = new MemoryStream(signedbytes); AlternateView av = new AlternateView(ms, "application/pkcs7-mime; smime-type=signed-data;name=smime.p7m"); msg.AlternateViews.Add(av); //7.寄出郵件 SmtpClient client = new SmtpClient("localhost", 25); client.UseDefaultCredentials = true; try { client.Credentials = new NetworkCredential("YourSmtpUserName", "YourSmtpPassword"); client.Send(msg); Label1.Text = "成功。"; } catch (Exception ex) { if (ex ==null) { Label1.Text = "不明錯誤。"; } else { Label1.Text = ex.Message.ToString(); } } } } } |
Email 憑證匯入本機憑證儲存區 ,請看下面這篇
[研究][C#]加密加簽寄信(使用Cpi.Net.SecureMail)(二)
http://shaurong.blogspot.com/2017/02/ccpinetsecuremail_13.html
憑證名稱請看下圖
********************************************************************************
以 Windows Server 2019 IIS SMTP 當 localhost port 25 寄信測試。
收件者是 MAIL2000 信箱可以收到信。
收件者是 Gmail 信箱收不到到信。(畢竟 IIS SMTP 不是正式有 FQDN 的 Mail Server )
收件者是公司信箱不一定,若在公司測試,可以收到信;家中電腦測試,收不到。(可能驗證來源 IP 是否公司使用的 IP )
收件者是 "十分鐘信箱",可以收到信。
********************************************************************************
2021-11-18
System.Security.Cryptography.CryptographicException
HResult=0x800B010A
Message=憑證鏈結無法建立於受信任的根授權。
Source=<無法評估例外狀況來源>
StackTrace:
<無法評估例外狀況堆疊追蹤>
********************************************************************************
2021-11-19
client.Send(msg); 會被 Fortify SCA 報告有問題
client.UseDefaultCredentials = true; 之後,client.Send(msg); 之前請加上程式
client.UseDefaultCredentials = true; try { client.Credentials = new NetworkCredential("YourSmtpUserName", "YourSmtpPassword"); client.Send(msg); Label1.Text = "成功。"; } |
改為
//Fortify SCA : Critical : Insecure Transport Mail Transmission
//需用加密連線,加上 client.UseDefaultCredentials = true; 和 client.EnableSsl = true;
// 只有 client.UseDefaultCredentials = true; 一個寄信成功,但是 Fortify SCA 會報告
client.UseDefaultCredentials = true; // OK
// 根據驗證程序,遠端憑證是無效的。=> 會出錯,下面這一行必須註解掉
// 原因:mail server和client使用ssl連線,但ssl憑證並沒有經過認證(ex:自簽憑證 Self Signed Certifcate)
// client.EnableSsl = true;
// 解決「根據驗證程序,遠端憑證是無效的。」,不管驗證結果 true 或 false,都當 true
//ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
//ServicePointManager.ServerCertificateValidationCallback += delegate { return true; };
System.Net.ServicePointManager.ServerCertificateValidationCallback += delegate { return true; };
client.EnableSsl = true;
try
{
client.Credentials = new NetworkCredential("YourSmtpUserName", "YourSmtpPassword");
client.Send(msg);
Label1.Text = "成功。";
} |
********************************************************************************
2021-11-29
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
會被Fortify SCA報告Insecure SSL: Server Identity Verification Disabled
解法
[研究]Fortify SCA報告Insecure SSL: Server Identity Verification Disabled
********************************************************************************
2021-11-29 補
[研究][ASP.NET]不能為收取目錄傳遞方法啟用 SSL。
********************************************************************************
(完)
相關
.NET Framework 中過時的類型
https://docs.microsoft.com/zh-tw/dotnet/framework/whats-new/obsolete-types
System.Web.Mail.SmtpMail 過時,建議的替代做法是 System.Net.Mail.SmtpClient。
System.Net.Mail.SmtpClient
https://docs.microsoft.com/zh-tw/dotnet/api/system.net.mail.smtpclient?view=netframework-4.8
System.Net.Mail.SmtpClient 淘汰,建議改用 https://github.com/jstedfast/MailKit 和 https://github.com/jstedfast/MimeKit
GitHub - jstedfast/MailKit: A cross-platform .NET library for IMAP, POP3, and SMTP.
https://github.com/jstedfast/MailKit
GitHub - jstedfast/MimeKit: A .NET MIME creation and parser library with support for S/MIME, PGP, DKIM, TNEF and Unix mbox spools.
https://github.com/jstedfast/MimeKit
[研究][C#][ASP.NET] 加簽寄信 (使用 System.Net.Mail.MailMessage)
https://shaurong.blogspot.com/2019/10/caspnet-systemnetmailmailmessage.html
[研究][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
[研究][C#][ASP.NET] IIS SMTP 寄信失敗,拒絕存取路徑
https://shaurong.blogspot.com/2019/10/caspnet-iis-smtp.html
[研究] [ASP.NET] [C#] [WebForm] 寄信問題
http://shaurong.blogspot.com/2017/06/aspnet-c-webform.html
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
ASP.NET寄發加密加簽信件
https://www.nccst.nat.gov.tw/ArticlesDetail?lang=zh&seq=1160
Cpi.Net.SecureMail
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
如何透過 .NET 送出一個包含 S/MIME 簽章的郵件
2009/06/06 21:20
https://blog.miniasp.com/post/2009/06/06/How-to-send-s-mime-email-using-net
沒有留言:
張貼留言