C# X509Certificate2无法在Linux上解析,但可以在Windows上工作

C# X509Certificate2无法在Linux上解析,但可以在Windows上工作,c#,linux,.net-core,x509certificate2,.net-standard,C#,Linux,.net Core,X509certificate2,.net Standard,从字节数组创建X509Certificate2实例在Windows上工作,但在Linux上失败,出现“加密异常” 在Windows上:创建了有效的X509Certificate2实例 在Linux上:引发异常: {System.Security.Cryptography.CryptographyException:找不到 原始签名人。 位于Internal.Cryptography.Pal.PkcsFormatReader.TryReadPkcs7(安全pkcs7handle-pkcs7,布尔

从字节数组创建X509Certificate2实例在Windows上工作,但在Linux上失败,出现“加密异常”

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


{System.Security.Cryptography.CryptographyException:找不到
原始签名人。
位于Internal.Cryptography.Pal.PkcsFormatReader.TryReadPkcs7(安全pkcs7handle-pkcs7,布尔单,ICertificatePal&certPal,列表'1&certPals)
位于Internal.Cryptography.Pal.PkcsFormatReader.TryReadPkcs7Der(字节[]rawData,布尔单,ICertificatePal&certPal,列表'1&certPals)
在Internal.Cryptography.Pal.CertificatePal.FromBlob(字节[]rawData,安全密码句柄password,X509keystrageFlags keystrageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(字节[]数据)
位于System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(字节[]rawData)
在/home/CertTest/Program.cs中的CertTest.Program.Main(字符串[]args)处:第14行}

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

您可以在此处找到一个有效的X509证书,该证书可以在Windows上解析,但不能在Linux上解析:

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

使用.Net Core 2.0.2进行测试
在Ubuntu 16.04、Ubuntu 17.10、OpenSuse Tumbleweed、Windows 10上,它不是X509证书,而是一些签名数据(PKCS#7格式)。Windows可以将PKCS#7格式的证书与证书路径中的其他证书一起导出。这很可能是你的情况。尝试将其重命名为p7b并在windows中打开。

PKCS#7中有两个证书:

  • CN=Microsoft Windows,序列号:33000016143159D469B7F968B0000000000161,由Microsoft Windows生产PCA 2011发布
  • CN=Microsoft Windows Production PCA 2011,序列号:610776560000000008,由Microsoft根证书颁发机构2010颁发
PKCS#7由微软时间戳PCA 2010的时间戳签署


为什么它可以在windows上工作,但不能在linux上工作我不知道。提交问题或尝试调试它

由于
new X509Certificate2()
在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解析器,我使用了Mono项目中的代码,但是Nuget上有几个可用的解析器。

Issue link:Thx获取PKCS#7解析器的技巧。我现在让它工作了!对于那些不想跳过我不得不做的循环的人,这个项目(免责声明:它是我的)实现了上面的解决方案。
 // 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));
// Get signing cert serial number from ASN.1
var serialNumber = asn1[1][0][4][0][1][1];