除了廣闊的互聯網,這個世界上還存在很多運行在公司內網的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分鐘不等,想要補充基礎知識的同學點這裏: