2017年2月13日 星期一

[研究][C#]用Email憑證作加密加簽寄信(使用Cpi.Net.SecureMail)(一)Console程式

[研究][C#]用Email憑證作加密加簽寄信(使用Cpi.Net.SecureMail)(一)Console城市

2017-02-13
2017-05-25 更新

測試環境:Windows Server 2016
開發工具:Visual Studio 2015 Enterprise with Update 3

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
下載得到 Cpi.Net.SecureMail_src.zip


原來程式碼是 Visual Studio 2008 (v9.0)開發的,用 Visual Studio 2015 開啟編譯正常。

如果要拿給其他方案使用,把編譯出來 bin 目錄下的檔案拷貝

Program.cs 原來內容,有些地方要修改
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Mail;
using System.Net;
using Cpi.Net.SecureMail;
using System.Security.Cryptography.X509Certificates;

namespace Tester
{
    class Program
    {
        static void Main(string[] args)
        {
            SecureMailMessage message = new SecureMailMessage();

            // Look up your signing cert by serial number in your cert store
            X509Certificate2 signingCert = CryptoHelper.FindCertificate("1B37D3");
            // Look up your encryption cert the same way
            X509Certificate2 encryptionCert = CryptoHelper.FindCertificate("22C590");

            // Load the recipient's encryption cert from a file.
            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 = "This is a signed and encrypted message";

            message.Body = "<h2>Sent from the Cpi.Net.SecureMail library!</h2>";
            message.IsBodyHtml = true;

            message.IsSigned = true;

            message.IsEncrypted = true;

            // Instantiate a good old-fashioned SmtpClient to send your message
            System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient("mymailserver", 25);

            // If your SMTP server requires you to authenticate, you need to specify your
            // username and password here.
            client.Credentials = new NetworkCredential("YourSmtpUserName", "YourSmtpPassword");

            client.Send(message);
        }
    }
}


首先要有一個有憑證的 Email,把該 Email 的憑證 .pfx 檔案做匯入到這台電腦。

(下圖) 開始匯入憑證 (.pfx) 檔案






********************************************************************************

(下圖) 用 IE 11 查憑證序號





注意:Email 寄信用密碼,和 Email 憑證匯入、匯出密碼是兩件事情。
你可以用 Outlook 或 WebMail 去確認一下你的 Email 寄信密碼。
你可以用 匯入、匯出 Email 憑證,去確認一下你的 Email 憑證密碼。

因為加密、加簽都用這個憑證,把 1B37D3 換成 3029,把 22C590 換成 3029,其他設定依據自己環境修改。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Mail;
using System.Net;
using Cpi.Net.SecureMail;
using System.Security.Cryptography.X509Certificates;

namespace Tester
{
    class Program
    {
        static void Main(string[] args)
        {
            SecureMailMessage message = new SecureMailMessage();

            // Look up your signing cert by serial number in your cert store
            // 設定簽章用的憑證
           // 注意,序號不需要空格
           // 憑證若過期,會抓不到憑證
           // 有的序號很長,不一定只有2組2位數,可能多組2位數
            // 序號複製過來時候,注意第一個數字(3) 之前,和最後一個數字(9) 之後,可能有看不到、也不會顯示 (也不顯示為空白) 的隱藏字元,滑鼠左右移動看看確認一下
            X509Certificate2 signingCert = CryptoHelper.FindCertificate("3029");
            //或下面寫法也可
            //X509Certificate2 signingCert = new X509Certificate2(@"c:\certs\MyCert.pfx");
            //X509Certificate2 signingCert = new X509Certificate2(@"c:\certs\MyCert.pfx", "憑證密碼");
            // 注意,是  "憑證密碼",不是 Email 的密碼
            // -----------

            // Look up your encryption cert the same way
            // 設定加密用的憑證
            X509Certificate2  encryptionCert = CryptoHelper.FindCertificate("3029");
            //或下面寫法也可
            //X509Certificate2 encryptionCert = new X509Certificate2(@"c:\certs\MyCert.pfx");
            //X509Certificate2 encryptionCert = new X509Certificate2(@"c:\certs\MyCert.pfx", "憑證密碼");
            // -----------

            // 設定收件者加密用的憑證
            // Load the recipient's encryption cert from a file.
            X509Certificate2  recipientCert = new X509Certificate2(@"c:\certs\MyCert.pfx");
            // 或
            // X509Certificate2  recipientCert = CryptoHelper.FindCertificate("3029");
            // X509Certificate2 encryptionCert = new X509Certificate2(@"c:\certs\MyCert.pfx", "憑證密碼");
            // -----------

            message.From = new SecureMailAddress("testuser1@smtp.mymailserver2.com", "Alice", encryptionCert, signingCert);
            message.To.Add(new SecureMailAddress("testuser1@smtp.mymailserver2.com", "Bob", recipientCert));

            message.Subject = "This is a signed and encrypted message";

            message.Body = "<h2>Sent from the Cpi.Net.SecureMail library!</h2>";
            message.IsBodyHtml = true;

            message.IsSigned = true;

            message.IsEncrypted = true;

            // Instantiate a good old-fashioned SmtpClient to send your message
            System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient("smtp.mymailserver2.com", 25);

            // If your SMTP server requires you to authenticate, you need to specify your
            // username and password here.
            client.Credentials = new NetworkCredential("testuser1", "123456");

            client.Send(message);
        }
    }
}


執行後可以正常寄出,以及收到信件。

********************************************************************************

不做匯入憑證的方法

如果不想匯入憑證

            // Look up your signing cert by serial number in your cert store
            X509Certificate2 signingCert = CryptoHelper.FindCertificate("3029");
            // Look up your encryption cert the same way
            X509Certificate2 encryptionCert = CryptoHelper.FindCertificate("3029");

            // Load the recipient's encryption cert from a file.
            X509Certificate2 recipientCert = new X509Certificate2(@"c:\certs\MyCert.pfx");

換成下面即可


            // Load the recipient's encryption cert from a file.
            X509Certificate2 recipientCert = new X509Certificate2(@"c:\certs\MyCert.pfx");
            X509Certificate2 signingCert = new X509Certificate2(@"c:\certs\MyCert.pfx");
            X509Certificate2 encryptionCert = new X509Certificate2(@"c:\certs\MyCert.pfx");



********************************************************************************
2017-05-24
Windows Server 2016 + IIS SMTP + Visual Studio 2017


這表示憑證需要密碼
            X509Certificate2 recipientCert = new X509Certificate2(@"c:\certs\MyCert.pfx");
要改寫為
            X509Certificate2 recipientCert = new X509Certificate2(@"c:\certs\MyCert.pfx" , "憑證密碼");

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

(完)

相關


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


沒有留言:

張貼留言