【问题标题】:Certificate's private key is exported as a different value?证书的私钥导出为不同的值?
【发布时间】:2017-05-04 10:03:42
【问题描述】:

我创建了一个自签名证书 (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# 导出 private 密钥时:

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 keys----- boundries,而是实际值。

附加信息,the PFX file

【问题讨论】:

  • 当您跳过 openssl 参数“-nodes”并实际提供相同的加密密码时会发生什么?
  • @DarkSquirrel42 我收到一个错误i.stack.imgur.com/joj8y.png
  • ok...openssl 的密码最少为 4 个字符...您可以在错误消息中看到...
  • @DarkSquirrel42 我将尝试导出使用“1234”密码的自签名并更新问题。
  • @DarkSquirrel42 我还是得到了不同的结果。我已将 pfx 文件添加到问题中。

标签: c# ssl openssl cryptography certificate


【解决方案1】:

X509ContentType.Cert 表示相同,因为证书是静态结构。如果你在循环中导出它,你总是会得到相同的答案。

X509ContentType.Pfx 表示不同,因为 PFX 结构中有随机盐。每个证书一个,每个私钥一个,最后一个。如果您在循环中将相同的公有+私有对导出为 PFX,则每次都会有所不同(288 位随机数据​​)。

base64 数据的结尾不同,因为它包含最后一个 salt 和其余数据(包括加密证书 salt 和加密密钥 salt)的 MAC。它还包含一个整数工作因子,Windows 选择为 2000,OpenSSL 选择为 2048;进一步区分 OpenSSL 和 Windows 导出。

因此,您所看到的是设计使然。如果您需要稳定的导出,则必须执行其他操作。如果您只是担心它们不同,那几乎肯定没问题。

【讨论】:

  • 这些输出不同,因为一个是私钥,另一个是 PFX。盐是什么并不重要。 openssl 导出中没有盐。
【解决方案2】:

为什么我在私钥中得到不同的结果?

您正在尝试做两件不同的事情。使用 openssl,您正在使用包含私钥和证书的 pfx 文件。在 c# 中,您正在使用带有私钥的证书表示形式,并且正在导出到 pfx 文件!

如何修复我的 C# 代码以产生与 openssl 的结果相同的结果?

C# 没有友好的功能,只能从 X509Certificate2 导出私钥(以类似 openssl 的方式)。正如 cmets 中提到的@darksquirell42,您可以使用X509Certificate2.PrivateKey 属性,然后将其转换为RSACryptoServiceProvider 并执行ToXmlString(true)。但这将为您提供 xml 结构中的私钥参数。然后,您必须获取每个参数并构造一个 ASN.1 结构 PKCS#1 或(恕我直言)PKCS#8。但默认情况下,C# 没有友好的方法来处理 ASN.1 对象。

或者你可以使用一些加密库来为你做这件事,比如 BouncyCastle。来自 BouncyCastle 的 This method 可能会有所帮助。

【讨论】:

  • @Royi 你能取消base64这两个私钥并使用ASN.1编辑器看看有什么不同吗?可能是一个是PKCS#1,另一个是PKCS#8。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-17
  • 1970-01-01
  • 1970-01-01
  • 2017-05-07
  • 2014-11-26
  • 1970-01-01
相关资源
最近更新 更多