我正在尝试解析X509 sertificate自定义扩展。 (我创建了一个自签名证书,其中包含“证书策略”类型的自定义扩展名)。我需要解析这个“证书策略”及其值。以编程方式,我可以得到自定义扩展名称“证书策略”,但我无法得到它的值..我使用的代码如下:
public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
var cert = (X509Certificate2)certificate;
foreach (X509Extension ext in cert.Extensions)
{
// AsnEncodedData x = new AsnEncodedData(ext.Oid, ext.RawData);
MessageBox.Show("Name: " + ext.Oid.FriendlyName + "\nValue: " + ext.Oid.Value);
}
return true;
}
此代码仅显示“证书策略”,但我需要下面显示的策略的解析元素:
证书政策要素下的值:
[1]Certificate Policy:
Policy Identifier=1.2.3.4
[2]Certificate Policy:
Policy Identifier=1.5.6.7.8
[3]Certificate Policy:
Policy Identifier=1.3.5.8
[3,1]Policy Qualifier Info:
Policy Qualifier Id=CPS
Qualifier:
Tarzano
[3,2]Policy Qualifier Info:
Policy Qualifier Id=User Notice
Qualifier:
Notice Reference:
Organization=Tarzano Ltd
Notice Number=1, 2, 3, 4
Notice Text=Buraya mesaj yazilabilir
感谢您的帮助!
答案 0 :(得分:0)
首先,您需要一个ASN.1解析器并使用X.509 ASN.1模块将扩展值解码为一组策略。我编写了一个托管类,它在我的PowerShell PKI模块中扩展了.NEt库中现有的X.509扩展。您可以从PSPKI项目站点获取托管的.dll或项目源:http://pspki.codeplex.com/以了解如何解码此扩展(我使用自己的ASN.1解析器,因此这里的代码片段不会太多感觉)如果你想拥有自己的东西(并且不依赖第三方组装)。
有一个PKI.Core.dll(也附带了源代码)。 X.509扩展类在System.Security.Cryptography.X509Certificates命名空间中定义。图书馆中此类的文档:http://pkix2.sysadmins.lv/library/html/T_System_Security_Cryptography_X509Certificates_X509CertificatePoliciesExtension.htm 扩展以类似的方式(它们从X509Extension类继承)作为.NET本机,但我的扩展是完全本机的(不使用CryptoAPI c ++函数,如在.NET中)。
答案 1 :(得分:0)
在.NET中似乎没有内置支持来解析x509扩展的ASN.1数据,超出.Format()
方法,如果它遇到任何未知对象,它将恢复为返回十六进制编码的字符串类型。
但广泛使用的BouncyCastle库https://www.bouncycastle.org/csharp/也可以通过NuGet获得,它具有良好的ASN.1解析支持。下面是一个示例,它打印证书扩展中找到的所有OID类型对象。它适用于.NET无法解析和显示的扩展。 Org.BouncyCastle.Asn1.Utilities.Asn1Dump.DumpAsString()
方法也很有用。
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using Org.BouncyCastle.Asn1;
public class AsnTest {
public static void Main() {
var certificate = new X509Certificate2(File.ReadAllBytes("Test.x509"));
foreach (var ext in certificate.Extensions) {
// This is as far as we reliably get with native .NET libraries, switch to BouncyCastle for additional parsing
var o = new Asn1InputStream(ext.RawData).ReadObject();
var q = new Queue<Asn1Sequence>();
var i = new List<DerObjectIdentifier>();
if (o is Asn1Sequence) {
q.Enqueue(o as Asn1Sequence);
} else if (o is DerObjectIdentifier) {
i.Add(o as DerObjectIdentifier);
}
while (q.Any()) {
var s = q.Dequeue();
i.AddRange(s.OfType<DerObjectIdentifier>());
foreach (var n in s.OfType<Asn1Sequence>())
{
q.Enqueue(n);
}
}
if (i.Any()) {
Console.WriteLine("Found the follwing OID value(s) in the " + ext.Oid.Value + " extension: " + string.Join(", ", i.Select(j => j.Id)));
} else {
Console.WriteLine("Found no OID values in the " + ext.Oid.Value + " extension.");
}
}
}
}