我出于测试目的创建了一个自签名证书 (pfx
)。
我可以通过以下方式导出 ist 公钥:
X509Certificate2 cer = new X509Certificate2();
X509Store store = new X509Store(StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var certificateCollection = store.Certificates.Find(...);
var cert = certificateCollection[0] ;
Console.WriteLine(Convert.ToBase64String(cert.Export( X509ContentType.Cert ), Base64FormattingOptions.InsertLineBreaks));
结果:
MIIDFTCCAf2gAw...........eFUpBB9C0/UNRmD7EAg==
这与openssl
命令一致:
$ openssl pkcs12 -in domain.name.pfx -clcerts -nokeys -out domain.name.crt
结果:
-----BEGIN CERTIFICATE-----
MIIDFTCCAf2gAw........9C0/UNRmD7EAg==
-----END CERTIFICATE-----
但是,当我通过 C# 导出私钥时:
Convert.ToBase64String(cert.Export( X509ContentType.Pfx ), Base64FormattingOptions.InsertLineBreaks)
我明白了:
MIIDFTCCAf2gAw............OVeFUpBB9C0/UNRmD7EAg==
使用openssl
命令时:
$ openssl pkcs12 -in domain.name.pfx -nocerts -nodes -out domain.name.key
我明白了:
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w.........6HNjF2h7uuFdvbH2VAVg=
-----END PRIVATE KEY-----
问题:
为什么我在私钥中得到不同的结果?如何修复我的 C# 代码以产生与 openssl 的结果相同的结果?
(注意 - 我不是在谈论 -----begin/end key-----
boundries ,而是实际值。
其他信息,the PFX file
最佳答案
X509ContentType.Cert
表示形式相同,因为证书是静态结构。如果您循环导出它,您将始终得到相同的答案。
X509ContentType.Pfx
表示形式有所不同,因为 PFX 结构中存在随机盐。每个证书一个,每个私钥一个,最后一个。如果您在循环中导出相同的公共(public)+私有(private)对作为 PFX,则每次都会不同(288 位随机数据)。
base64 数据的结尾有所不同,因为它包含最后一个盐和其余数据的 MAC(包括加密的证书盐和加密的 key 盐)。它还包含一个整数工作因子,Windows 选择为 2000,OpenSSL 选择为 2048;进一步区分 OpenSSL 和 Windows 导出。
所以你所看到的是设计使然。如果你需要稳定的导出,你就必须做其他事情。如果您只是担心它们有所不同,那几乎肯定没问题。
关于c# - 证书的私钥导出为不同的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43779806/