Как вы разбираете альтернативные имена субъекта из X509Certificate2?

Есть ли простой способ получить альтернативные имена объекта из объекта X509Certificate2?

        foreach (X509Extension ext in certificate.Extensions)
        {
            if (ext.Oid.Value.Equals(/* SAN OID */"2.5.29.17"))
            {
                byte[] raw = ext.RawData;
                // ?????? parse to get type and name ????????
            }
        }

Ответ 1

Используйте Способ форматирования расширения для версии для печати. ​​

X509Certificate2 cert = /* your code here */;

foreach (X509Extension extension in cert.Extensions)
{
    // Create an AsnEncodedData object using the extensions information.
    AsnEncodedData asndata = new AsnEncodedData(extension.Oid, extension.RawData);
    Console.WriteLine("Extension type: {0}", extension.Oid.FriendlyName);
    Console.WriteLine("Oid value: {0}",asndata.Oid.Value);
    Console.WriteLine("Raw data length: {0} {1}", asndata.RawData.Length, Environment.NewLine);
    Console.WriteLine(asndata.Format(true));
}

Ответ 2

Чтобы получить "Альтернативное имя субъекта" из сертификата:

X509Certificate2 cert = /* your code here */;

Console.WriteLine("UpnName : {0}{1}", cert.GetNameInfo(X509NameType.UpnName, false), Environment.NewLine);

Ответ 3

Я создал функцию для этого:

private static List<string> ParseSujectAlternativeName(X509Certificate2 cert)
{
            var result = new List<string>();

            var subjectAlternativeName = cert.Extensions.Cast<X509Extension>()
                                                .Where(n => n.Oid.FriendlyName.EqualsCase(SubjectAlternativeName))
                                                .Select(n => new AsnEncodedData(n.Oid, n.RawData))
                                                .Select(n => n.Format(true))
                                                .FirstOrDefault();

            if (subjectAlternativeName != null)
            {
                var alternativeNames = subjectAlternativeName.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);

                foreach (var alternativeName in alternativeNames)
                {
                    var groups = Regex.Match(alternativeName, @"^DNS Name=(.*)").Groups;

                    if (groups.Count > 0 && !String.IsNullOrEmpty(groups[1].Value))
                    {
                        result.Add(groups[1].Value);
                    }
                }
            }

            return result;           
}