除了廣闊的網際網路,這個世界上還存在很多執行在公司內網的Web Application。假設有團隊A提供的網站A,現團隊B需要將網站B與之整合。網站A已使用了自籤的SSL證書。團隊B希望能夠匯出該SSL證書並轉換成PEM格式,供Nginx配置給網站B使用。
接著假設上述假設成立,世界上就是有這些奇奇怪怪的需求,那麼我們要怎麼做呢?
在Windows上,切合我們的.NET學習主題,當然是使用C#查詢當前計算機上,需要被我們匯出的證書Certificate。我們以用於IIS Express的ASP.NET Core HTTPS development certificate舉例,根據證書的頒發者Issuer或FriendlyName來查詢該證書。
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine, OpenFlags.ReadOnly); X509Certificate2? wantedCertificate = null; foreach (var certificate in store.Certificates) { if (certificate.Issuer == "CN=localhost") { wantedCertificate = certificate; } }
在獲取該證書的X509Certificate2物件後,我們要做的是生成供Nginx配置使用的PEM格式的證書crt檔案和私鑰key檔案。
其實如果Nginx能夠直接支援Windows的PFX格式證書,我們可以在IIS直接手工匯出PFX證書,或者透過PowerShell指令碼實現上述C#程式碼相同的匹配查詢和匯出PFX證書的操作。
但現實就是這麼悲劇,我們需要摒棄唾手可得的PFX證書,轉而去想辦法折騰PEM格式的證書檔案。
網上搜尋給出的解答,都是透過OpenSSL工具轉換得到crt檔案和key檔案。問題實際的需求是希望在安裝過程自動地找到並使用網站A的證書,而不是由工程實施人員手工操作,同時也並不希望在目標Windows機器上安裝OpenSSL。
考慮到PEM格式檔案就是Base64編碼的文字檔案。以"-----BEGIN CERTIFICATE-----" 字串開頭,和以 "-----END CERTIFICATE-----"結尾。所以我們可以透過C#的X509Certificate2物件來自己生成crt和key檔案,無需依賴OpenSSL。
var rawData = wantedCertificate.RawData; using (var write = new StreamWriter(@"C:\temp\Sample.crt")) { write.WriteLine("-----BEGIN CERTIFICATE-----"); write.WriteLine(Convert.ToBase64String(rawData, Base64FormattingOptions.InsertLineBreaks)); write.WriteLine("-----END CERTIFICATE-----"); } var privateKey = wantedCertificate.GetRSAPrivateKey(); if (privateKey != null) { var keyData = privateKey.ExportRSAPrivateKey(); using (var write = new StreamWriter(@"C:\temp\Sample.key")) { write.WriteLine("-----BEGIN RSA PRIVATE KEY-----"); write.WriteLine(Convert.ToBase64String(keyData, Base64FormattingOptions.InsertLineBreaks)); write.WriteLine("-----END RSA PRIVATE KEY-----"); } }
生成的檔案用VSCode開啟,大體長成這個樣子:
生成的檔案長這樣:
至於怎麼在Nginx中配置SSL證書,或者是ASP.NET Core怎麼配置SSL證書,那就是另外一個故事了。
程式碼示例放在GitHub:
以下連結,是MS Learn上Windows開發的入門課程,單個課程三十分鐘到60分鐘不等,想要補充基礎知識的同學點這裡: