从 X509 证书读取 RSA 私钥会导致 Windows Server 2016 与 Windows Server 2019 上的输出不同

Reading RSA private key from X509-certificate results in different output on Windows Server 2016 vs. Windows Server 2019

这是我的问题:

在 C#/.NET-4.8 中,我在 2 个服务器上使用 P12 证书和 RSA 私钥。 一台服务器运行 Windows Server 2016,另一台运行 Windows Server 2019。 当我在两台服务器上比较同一证书的 RSA 私钥时,输出不一样。 “私有指数”(在“D”属性中找到)不一样。

有人知道为什么会这样吗?

额外信息: 代码每次运行时都会输出相同的密钥(每个系统)(这当然很好)。 该代码在 Windows 10、Windows 11 和 Windows Server 2019 上输出相同的私钥,但在 Windows Server 2016 上不同。

读出证书密钥的代码是:

using (var rsaPrivateKey = _certificate.GetRSAPrivateKey())
{
   var parameters = rsaPrivateKey.ExportParameters(true);
   privateExponent = BitConverter.ToString(parameters.D); // privateExponent (parameters.D) is the components which is not the same on each system.

   privateKeyXml = rsaPrivateKey.ToXmlString(true); // In privateKeyXml, only the privateExponent changes.
}

在此先感谢您的帮助!

要使答案有意义,您需要具备两条背景知识:

  • RSA 私钥被冗余编码。 (n, e, d, p, q, dp, dq, qInv) 可能真的只是 (n, e, p, q)
    • 过去,计算 d/dp/dq/qInv 是“困难的”,因此文件格式是“省去重新计算的麻烦”——尽管这可能会导致值不一致。
  • 有两种不同的方法来计算 d(“lambda”和“phi”),两种值都有效。

Windows CNG,从 Vista 到 2019 年,在导入密钥时丢弃了 d/dp/dq/qInv 值,并使用(我相信)lambda 方法重新计算它们。

出于某种原因,在 ~2019 年,他们要么改为强制使用 phi 进行计算,要么开始保存导入值并在导出时忠实地报告它们。

无论如何,这并不重要,因为真正的密钥只是 (n, e, p, q)。只要这 4 个不变,您就拥有相同的密钥。