除了广阔的互联网,这个世界上还存在很多运行在公司内网的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来查找该证书。

.NET 6学习笔记(6)——SSL证书的导出和格式转换-LMLPHP

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打开,大体长成这个样子:

.NET 6学习笔记(6)——SSL证书的导出和格式转换-LMLPHP

生成的文件长这样:

.NET 6学习笔记(6)——SSL证书的导出和格式转换-LMLPHP

至于怎么在Nginx中配置SSL证书,或者是ASP.NET Core怎么配置SSL证书,那就是另外一个故事了。

代码示例放在GitHub:

GitHub - manupstairs/GenerateCertUsingCSharp: The example shows how to use CSharp to generate certificates and keys in PEM format.

以下链接,是MS Learn上Windows开发的入门课程,单个课程三十分钟到60分钟不等,想要补充基础知识的同学点这里:

开始使用 Visual Studio 开发 Windows 10 应用

开发 Windows 10 应用程序

编写首个 Windows 10 应用

创建 Windows 10 应用的用户界面 (UI)

增强 Windows 10 应用的用户界面

在 Windows 10 应用中实现数据绑定

02-05 20:14