как разобрать политику сертификата пользовательского расширения сертификата X509 ssl?

Я пытаюсь разобрать пользовательское расширение сертификата X509. (Я создал самоподписанный сертификат с пользовательскими расширениями типа «политика сертификатов»). Мне нужно проанализировать эту «политику сертификатов» и ее значения. Программно я могу получить имя пользовательского расширения, которое является «политикой сертификатов», но я не могу получить его значения. Код, который я использую, выглядит следующим образом:

    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

Спасибо за помощь !


person user2084339    schedule 19.10.2014    source источник


Ответы (2)


Сначала вам понадобится синтаксический анализатор ASN.1 и модули X.509 ASN.1 для декодирования значения расширения в набор политик. Я написал управляемый класс, который расширяет существующие расширения X.509 из библиотеки .NET в моем модуле PowerShell PKI. Вы можете получить управляемые файлы .dll или исходные коды проектов с сайта проекта PSPKI: 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).

person Crypt32    schedule 20.10.2014
comment
Спасибо за ответ CryptoGuy. Этот класс решил мою проблему: msdn.microsoft.com/en-us/library/ - person user2084339; 25.10.2014

Похоже, что в .NET нет встроенной поддержки анализа данных ASN.1 расширений x509, кроме метода .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.");
            }
        }
    }
}
person Otto G    schedule 19.05.2017