除了广阔的互联网,这个世界上还存在很多运行在公司内网的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分钟不等,想要补充基础知识的同学点这里: