Как извлечь электронную почту из сертификата X509 в .NET?

Я ищу способ получить адрес электронной почты (строку) из сертификата X509. Я не могу найти готовое свойство или метод для этого. Поэтому для меня лучше всего (наиболее гибко для будущих задач) получить значение по OID ASN (1.2.840.113549.1.9.1). Как я могу сделать это, используя собственный класс .NET?

Я пытался использовать AsnEncodedData.format, но безрезультатно. Есть ли способ сделать это?


person StanislavT.    schedule 21.11.2014    source источник
comment
Пример на эта страница может помочь?   -  person Bridge    schedule 21.11.2014
comment
Спасибо! Вот и все! Но что вы могли бы предложить по поводу другого решения (получить любое расширение, такое как электронная почта, по соответствующему OID)?   -  person StanislavT.    schedule 21.11.2014
comment
Извините, у меня нет опыта в этой области, я просто хорошо разбираюсь в Google, и у вас не было других комментариев/ответов :)   -  person Bridge    schedule 21.11.2014
comment
Это невозможно с помощью встроенных инструментов. Вам придется искать сторонние библиотеки. Но спасибо за идею, действительно стоит подумать.   -  person Crypt32    schedule 21.11.2014
comment
Спасибо, КриптоГай! Это сэкономит мне много времени! И последний вопрос: какую стороннюю библиотеку вы предпочитаете? Есть ли альтернативы BouncyCastle, которые недостаточно документированы?   -  person StanislavT.    schedule 22.11.2014
comment
@Мост, спасибо. У меня нет опыта в этой области, но кажется, что x509.GetNameInfo(X509NameType.EmailName, false) — это то, что я искал.   -  person Koray    schedule 03.05.2019


Ответы (1)


Если вы можете использовать сторонние инструменты, вы можете посмотреть мой модуль Powershell PKI. Этот модуль содержит библиотеку PKI.Core.dll, которая представляет собой набор API. API достаточно хорошо задокументированы в документации библиотеки.

С этой библиотекой я бы использовал следующий статический метод и пользовательский класс:

using PKI.ASN;
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace MyNamespace {
    public class RdnAttribute {
        public Oid OID { get; set; }
        public String Value { get; set; }
    }
    public class MyClass {
        public static List<RdnAttribute> GetRdnAttributes(X500DistinguishedName name) {
            List<RdnAttribute> retValue = new List<RdnAttribute>();
            ASN1 asn = new ASN1(name.RawData);
            asn.MoveNext();
            do {
                ASN1 asn2 = new ASN1(asn.Payload);
                asn2.MoveNext();
                List<Byte> oidRawData = new List<Byte>(asn2.Header);
                oidRawData.AddRange(asn2.Payload);
                Oid oid = ASN1.DecodeObjectIdentifier(oidRawData.ToArray());
                asn2.MoveNext();
                String value;
                switch (asn2.Tag) {
                    case (Byte)ASN1Tags.UniversalString:
                        value = Encoding.UTF32.GetString(asn2.Payload);
                        break;
                    case (Byte)ASN1Tags.BMPString:
                        value = Encoding.BigEndianUnicode.GetString(asn2.Payload);
                        break;
                    default:
                        value = Encoding.UTF8.GetString(asn2.Payload);
                        break;
                }
                retValue.Add(new RdnAttribute { OID = oid, Value = value });
            } while (asn.MoveNextCurrentLevel());
            return retValue;
        }
    }
}

Метод возвращает массив (неупорядоченный) атрибутов RDN, где свойство OID содержит идентификатор объекта RDN, а свойство Value содержит текстовое значение RDN. Если вы можете использовать Linq, вы можете быстро искать в коллекции: somearray.Where(x => x.OID.Value == "1.2.840.113549.1.9.1");. Обратите внимание, что определенные атрибуты RDN могут появляться несколько раз, поэтому не следует использовать методы First* или Single* Linq.

person Crypt32    schedule 22.11.2014