【问题标题】:X509Certificate2 fails to parse on Linux but works on WindowsX509Certificate2 无法在 Linux 上解析,但可以在 Windows 上运行
【发布时间】:2018-05-25 20:52:40
【问题描述】:

从字节数组创建 X509Certificate2 实例在 Windows 上有效,但在 Linux 上失败并出现“CryptographicException”。

static void Main(string[] args)
{
    var cert = new X509Certificate2(Cert.CertBytes);
}

在 Windows 上:创建了有效的 X509Certificate2 实例 在 Linux 上:抛出异常:

{System.Security.Cryptography.CryptographicException: Cannot find the original signer. at Internal.Cryptography.Pal.PkcsFormatReader.TryReadPkcs7(SafePkcs7Handle pkcs7, Boolean single, ICertificatePal& certPal, List`1& certPals) at Internal.Cryptography.Pal.PkcsFormatReader.TryReadPkcs7Der(Byte[] rawData, Boolean single, ICertificatePal& certPal, List`1& certPals) at Internal.Cryptography.Pal.CertificatePal.FromBlob(Byte[] rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] data) at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData) at CertTest.Program.Main(String[] args) in /home/CertTest/Program.cs:line 14}

我做错了吗?我假设一个证书就是一个证书,不管它是在哪个操作系统上解析的。

您可以在此处找到可以在 Windows 上解析但不能在 Linux 上解析的有效 X509 证书:https://gist.github.com/secana/9c13f8fa495681f8a30adb5d8754450e

我尝试了多个证书,但没有一个可以在 Linux 上运行。我没有 Mac,所以我无法测试它是否可以在那里工作。

使用 .Net Core 2.0.2 测试 在 Ubuntu 16.04、Ubuntu 17.10、OpenSuse Tumbleweed、Windows 10 上

【问题讨论】:

标签: c# linux .net-core x509certificate2 .net-standard


【解决方案1】:

它不是 X509 证书,而是一些签名数据(PKCS#7 格式)。 Windows 可以导出 PKCS#7 格式的证书以及证书路径中的其他证书。这很可能是你的情况。尝试将其重命名为 p7b 并在 windows 中打开它。

PKCS#7 中有两个证书:

  • CN=Microsoft Windows,序列号:330000016143159d469b7f968b000000000161,由Microsoft Windows Production PCA 2011发布
  • CN=Microsoft Windows Production PCA 2011,序列号:61077656000000000008,由 Microsoft Root Certificate Authority 2010 颁发

PKCS#7 使用来自 Microsoft Time-Stamp PCA 2010 的时间戳进行签名。

我不知道为什么它可以在 Windows 上运行,但不能在 linux 上运行。提交问题here 或尝试调试它。

【讨论】:

  • 感谢 PKCS#7 解析器的提示。我现在开始工作了!
【解决方案2】:

由于new X509Certficate2() 在 Linux 下不会像在 Windows 下那样返回签名证书,因此您必须解析 PKCS7 的 ASN.1 结构才能找到签名证书。

例子:

 // Import all certificates in the structure into a collection
 var collection = new X509Certificate2Collection();
 collection.Import(Cert.CertBytes);

 // Find the signing cert
 var signingCert = collection.Cast<X509Certificate2>().FirstOrDefault(cert => 
 string.Equals(cert.SerialNumber, SignerSerialNumber, 
 StringComparison.CurrentCultureIgnoreCase));

唯一的难点是获取签名证书的序列号。为此,我解析了 ASN.1 结构。序列号在ASN.1路径1/0/4/0/1/1中。

例子:

// Get signing cert serial number from ASN.1
var serialNumber = asn1[1][0][4][0][1][1];

作为 ASN.1 解析器,我使用了 Mono 项目中的代码,但 Nuget 上有几个可用的解析器。

【讨论】:

  • 对于那些不想跳过我不得不跳的循环的人,这个项目(免责声明:它是我的)实现了上面的解决方案。 github.com/secana/PeNet
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-12
  • 2020-04-08
  • 2019-03-07
  • 2011-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多