【ASP.NET Core】自己程式設計來生成自簽名的伺服器證書

東邪獨孤發表於2022-04-20

如果專案不大,或者是客戶公司內部使用,或者不想花錢購買證書,又或者用於開發階段測試……完全可以使用自簽名證書。

所謂自籤,就是自己給自己簽名頒發的證書,自給自足,豐衣足食。

生成證書的方法和工具很多,你可能會想到用以前 .NET Framework SDK工具,你可能想到用 OpenSSL 工具。但是,與其用工具,還不如直接呼叫 .NET 自身的 API ,在專案中直接建立證書來得方便。金鑰隨機即可,建立證書後寫入到 .pfx 檔案中。這樣做也很方便,有利於程式搬家。

好,鬼話不多說,我們們開始今天的表演。

首先,寫一個類,簡單粗暴易用。

    public class CerMaker
    {
        public static async Task CreateSslCertAsync(string subName,
                                       DateTime bgDate,
                                       DateTime endDate,
                                       string outFile,
                                       string? passWd)
        {
            // 引數檢查
            if(subName is null or { Length: < 3 })
            {
                throw new ArgumentNullException(nameof(subName));
            }
            if(endDate <= bgDate)
            {
                throw new ArgumentException("結束日期應大於開始日期");
            }
            // 隨機金鑰
            RSA key = RSA.Create(1024);
            // 建立CRT
            CertificateRequest crt = new(subName, key, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
            // 建立自簽名證書
            var cert = crt.CreateSelfSigned(bgDate, endDate);
            // 將證書寫入檔案
            byte[] data = cert.Export(X509ContentType.Pfx, passWd);
            await File.WriteAllBytesAsync(outFile, data);
        }
    }

 

一個類,一個靜態方法,引數 subName 表示證書的標題文字,一般使用域名,比如 CN=xpxp.org、CN=www.sb.edu.cn 等。

引數 bgDate 表示證書有效期的起始日期,一般我們們選生成證書當前時間;

引數 endDate 表示證書有效期的終止日期,即過期時間;

引數 outFile 表示 .pfx檔案的儲存路徑,相對的絕對的都行,有寫許可權就行;

引數 passWd 表示給.pfx檔案加密的密碼,可以隨便定義。

 

生成的過程如下:

1、RSA.Create 方法建立金鑰(包含公/私鑰),內容是隨機生成的,1024指金鑰的長度為1024位,你也可以指定為4096位;

2、建立一個 CertificateRequest 例項:

  CertificateRequest crt = new(subName, key, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

第一個引數傳的證書的標題,第二個引數是剛剛隨機生成的金鑰,第三個引數是雜湊演算法,此處選的是 SHA256 演算法;第四個引數不用多想,就用 PKCS1 就行(這是塊填充行為)。

3、呼叫 CreateSelfSigned 方法,就能建立證書了;

4、呼叫證書的 Export 方法把其匯出為 .pfx 格式的資料;

5、把資料寫入檔案,收工。

---------------------------------------------

你看,多 Easy 的事,不用費心去找什麼工具了,自己動一動手就成了。

 

然後,在 ASP.NET Core 專案裡,我們們先檢查一下證書檔案存不存在,如果不存在,自動生成一個。

// 先建立自簽名證書
const string CER_FILE = "host.pfx";
const string PASSWD = "dagongji";
const string SUB_NAME = "CN=萬年坑玩具廠.com.cn";
DateTime today = DateTime.Now;
DateTime endday = today.AddDays(365);
if(!File.Exists(CER_FILE))
{
    await CerMaker.CreateSslCertAsync(SUB_NAME, today, endday, CER_FILE, PASSWD);
}

 

一般來說,專案的證書並不需要換來換去,所以,我們們可以把生成證書的程式碼寫到一個控制檯應用專案中,生成一個命令列工具,自己留著用,只需要執行它生成證書檔案,再放到 ASP.NET Core 專案的目錄下就可以了。

 

在 build 應用程式之前,配置一下 Kestrel 伺服器,使用我們們自己生成的證書檔案。

var builder = WebApplication.CreateBuilder(args);
// 配置證書
builder.WebHost.ConfigureKestrel(opt =>
{
    opt.ConfigureHttpsDefaults(cnncop =>
    {
        cnncop.ServerCertificate = new X509Certificate2(CER_FILE, PASSWD);
    });
});
var app = builder.Build();

這是用於獨立啟動的 ASP.NET Core 應用程式(使用內建的 Kestrel 伺服器)。如果你用的 IIS,那麼證書是在IIS管理器中配置;如果你用的是 nginx,也是在伺服器的配置檔案中配置證書,而不是在 ASP.NET Core 程式碼中。

 

由於證書是自己籤給自己的,不是從權威機構買的,所以,當瀏覽器訪問時,會有不安全提示。只要你確認是你自己的證書,或者客戶知道這是他們自家可用的證書就可以了。瀏覽器肯定不認識自簽證書的。

 

 

 

 

好了,今天這個好用的技巧就分享到這兒了。

相關文章