如何在SslStream.AuthenticateAsClient?(.NET4)过程中从X509Certificate对象中提取域名

brvekthn  于 5个月前  发布在  .NET
关注(0)|答案(4)|浏览(66)

我有一个由SslStream.AuthenticateAsClient调用的RemoteCertificateValidationCallback函数,它被传递了一个X509Certificate对象。
我想从该证书中提取名称,这样,如果我将该字符串传递给AuthenticateAsClient,它就会通过。(假设没有其他问题。)
(Note:Subject属性包含域名,但它位于“CN=...,S=...”等格式的字符串中。
另请参阅:How to extract CN from X509Certificate in Java?(针对Java提出了类似的问题,但我找不到这些答案中提到的.NET的类似类。
(以下是尤金的回答。)
我试过了...

var cert2 = new System.Security.Cryptography.X509Certificates.X509Certificate2();
cert2.Import(certificate.GetRawCertData());

字符串
.但是cert2.SubjectName.Name仍然具有CN= etc格式。我做错了吗?

j91ykkif

j91ykkif1#

我是这样做的:

var cert2 = new X509Certificate2(cert);
string hostName = cert2.GetNameInfo(X509NameType.DnsName, false);

字符串
您还可以检查证书是否有效:

bool valid = cert2.Verify();


(See this question用于描述X509Certificate2类)

bwleehnv

bwleehnv2#

对于我的证书字符串,通过像这样的小调整,它工作得更好

public static List<string> Parse(string data, string delimiter)
{
    if (data == null) return null;
    if (!delimiter.EndsWith("=")) delimiter = delimiter + "=";
    if (!data.Contains(delimiter)) return null;
    //base case
    var result = new List<string>();
    int start = data.IndexOf(delimiter) + delimiter.Length;
    int length = data.IndexOf(',', start) - start;
    if (length == 0) return null; //the group is empty
    if (length > 0)
    {
        result.Add(data.Substring(start, length));
        //only need to recurse when the comma was found, because there could be more groups
        var rec = Parse(data.Substring(start + length), delimiter);
        if (rec != null) result.AddRange(rec); //can't pass null into AddRange() :(
    }
    else //no comma found after current group so just use the whole remaining string
    {
        result.Add(data.Substring(start));
    }
    return result;
}

字符串
...

var name = Parse(_cert.Subject, "CN").FirstOrDefault();
var email = Parse(_cert.Subject, "E").FirstOrDefault();

jjjwad0x

jjjwad0x3#

使用GetRawCertData方法获取证书的DER数据。然后创建X509 Certificate 2对象的示例,并使用Import()方法加载原始证书数据。然后使用SubjectName属性访问各个主题字段。注意-您还需要检查主题替代名称扩展,但不幸的是,在.NET Framework类中没有简单的方法来做到这一点(您可能会发现有必要使用第三方PKI库进行适当的证书验证和管理)。

9bfwbjaz

9bfwbjaz4#

我使用以下方法解析AD返回的字符串,它可能有助于解析您接收的数据:

/// <summary>
/// Recursively searches the supplied AD string for all groups.
/// </summary>
/// <param name="data">The string returned from AD to parse for a group.</param>
/// <param name="delimiter">The string to use as the seperator for the data. ex. ","</param>
/// <returns>null if no groups were found -OR- data is null or empty.</returns>
public static List<string> Parse(string data, string delimiter)
{
    if (data == null) return null;

    if (!delimiter.EndsWith("=")) delimiter = delimiter + "=";

    //data = data.ToUpper(); // why did i add this?
    if (!data.Contains(delimiter)) return null;

    //base case
    var result = new List<string>();
    int start = data.IndexOf(delimiter) + 3;
    int length = data.IndexOf(',', start) - start;
    if (length == 0) return null; //the group is empty
    if (length > 0)
    {
        result.Add(data.Substring(start, length));

        //only need to recurse when the comma was found, because there could be more groups
        var rec = Parse(data.Substring(start + length), delimiter);
        if (rec != null) result.AddRange(rec); //can't pass null into AddRange() :(
    }
    else //no comma found after current group so just use the whole remaining string
    {
        result.Add(data.Substring(start));            
    }

    return result;
}

字符串
因此,给予一个字符串,如“CN=my common name,CN=another common name,O=my orginization”,它将返回一个包含两个公共名称的列表。

相关问题