X509Certificate2 在 Linux 上解析失败但在 Windows 上有效
X509Certificate2 fails to parse on Linux but works on Windows
从字节数组创建 X509Certificate2 实例在 Windows 上有效,但在 Linux 上失败,出现 "CryptographicException".
static void Main(string[] args)
{
var cert = new X509Certificate2(Cert.CertBytes);
}
On 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}
我是不是做错了什么?我假设证书就是证书,不管它是在 OS 上解析的。
您找到一个有效的 X509 证书,可以在 Windows 上解析,但不能在 Linux 上解析:https://gist.github.com/secana/9c13f8fa495681f8a30adb5d8754450e
我尝试了多个证书,但 none 在 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,序列号:330000016143159d469b7f968b000000000161,微软发行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 或尝试调试它。
因为 new X509Certficate2()
不像 Windows 那样 return Linux 下的签名证书,你必须解析 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 上有几个可用的解析器。
从字节数组创建 X509Certificate2 实例在 Windows 上有效,但在 Linux 上失败,出现 "CryptographicException".
static void Main(string[] args)
{
var cert = new X509Certificate2(Cert.CertBytes);
}
On 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}
我是不是做错了什么?我假设证书就是证书,不管它是在 OS 上解析的。
您找到一个有效的 X509 证书,可以在 Windows 上解析,但不能在 Linux 上解析:https://gist.github.com/secana/9c13f8fa495681f8a30adb5d8754450e
我尝试了多个证书,但 none 在 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,序列号:330000016143159d469b7f968b000000000161,微软发行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 或尝试调试它。
因为 new X509Certficate2()
不像 Windows 那样 return Linux 下的签名证书,你必须解析 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 上有几个可用的解析器。