C#生成自签名证书文件 C#如何创建用于测试的pfx或cer文件

来源:这里教程网 时间:2026-02-21 17:41:35 作者:

X509Certificate2
CertificateRequest
生成自签名证书

.NET Core 2.1+ 和 .NET 5+ 提供了纯托管的证书生成功能,无需调用 Windows CryptoAPI 或 OpenSSL。核心是

CertificateRequest
类,它支持 RSA/ECDSA、指定扩展(如 SAN)、有效期等。直接 new 一个请求,调用
CreateSelfSigned
即可拿到
X509Certificate2
实例。

常见错误:在 .NET Framework 4.7.2 及更早版本中,

CertificateRequest
不可用,必须降级用
CspParameters
+
RSA
手动构造,或改用第三方库(如 BouncyCastle)。

推荐密钥长度:RSA 至少
2048
,ECDSA 推荐
secp256r1
必须设置
Subject
(哪怕只是
"CN=localhost"
),否则
CreateSelfSigned
ArgumentException
若需浏览器信任(如本地 HTTPS 测试),务必添加
SubjectAlternativeName
扩展,否则 Chrome 会报
NET::ERR_CERT_INVALID

导出为
.pfx
(含私钥)和
.cer
(仅公钥)

X509Certificate2
Export
方法支持多种格式。导出
.pfx
必须传入密码且使用
X509ContentType.Pkcs12
;导出
.cer
推荐用
X509ContentType.Cert
(DER 编码)或
X509ContentType.Pkcs7
(PEM 封装的 Base64),后者更易被文本编辑器查看。

容易踩的坑:

Export(X509ContentType.Cert)
不包含私钥,但如果你从 PFX 文件加载证书后没显式指定
X509KeyStorageFlags.Exportable
,即使原 PFX 有私钥,
Export
也会失败并抛
CryptographicException: The parameter is incorrect

写入
.pfx
:用
cert.Export(X509ContentType.Pkcs12, "password123")
,再
File.WriteAllBytes("test.pfx", bytes)
写入 PEM 格式
.cer
:先
cert.Export(X509ContentType.Cert)
得到 DER 字节数组,再手动 Base64 编码并套上
-----BEGIN CERTIFICATE-----
头尾
避免用
cert.Export(X509ContentType.SerializedCert)
—— 它是 .NET 私有序列化格式,其他工具无法识别

给证书加 Subject Alternative Name(SAN)扩展

现代 HTTPS 测试几乎必加 SAN,否则

https://localhost
https://127.0.0.1
会被浏览器拒绝。.NET 的
CertificateRequest
允许通过
AddExtension
注入
X509Extension
,但更稳妥的是用内置的
X509SubjectAlternativeNameExtension
构造器。

注意:不能把 DNS 名和 IP 地址混在一个

X509SubjectAlternativeNameExtension
实例里传进去 —— 必须分开调用两次
AddDnsName
AddIpAddress
,否则解析失败导致证书无效。

添加 localhost:调用
req.AddDnsName("localhost")
添加 IPv4:用
req.AddIpAddress(IPAddress.Parse("127.0.0.1"))
添加通配符(仅限测试):
req.AddDnsName("*.test.local")
,但需确保本地 hosts 绑定对应域名

完整示例:生成带 SAN 的 PFX 用于 Kestrel HTTPS 测试

以下代码在 .NET 6+ 下可直接运行,生成的

test.pfx
可直接配置到
Program.cs
的 Kestrel HTTPS 端点:

var distinguishedName = new X500DistinguishedName("CN=localhost");
using var req = new CertificateRequest(distinguishedName, RSA.Create(2048), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
req.AddExtension(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.KeyEncipherment, critical: true);
req.AddDnsName("localhost");
req.AddIpAddress(IPAddress.IPv6Loopback); // 同时支持 [::1]
using var cert = req.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddYears(1));
File.WriteAllBytes("test.pfx", cert.Export(X509ContentType.Pkcs12, "devpass"));

如果后续要用这个 PFX 在 Linux/macOS 上跑 ASP.NET Core,记得确认 OpenSSL 版本 ≥ 1.1.1,否则可能因 PKCS#12 密码派生算法不兼容而加载失败。

相关推荐