如果您使用的是X509Certificate2,则可以使用本机方法提取DNS名称.DNS名称通常等效于主证书的"主题"字段中的公用名称RDN:
x5092Cert.GetNameInfo(X509NameType.SimpleName, false);
Run Code Online (Sandbox Code Playgroud)
深入研究.NET源代码之后,似乎有一个内部实用程序类,可以将专有名称解析为它们的不同组件。不幸的是,该实用工具类并未公开,但是您可以使用反射来访问它:
string dn = "CN=TestGroup,OU=Groups,OU=UT-SLC,OU=US,DC=Company,DC=com";
Assembly dirsvc = Assembly.Load("System.DirectoryServices");
Type asmType = dirsvc.GetType("System.DirectoryServices.ActiveDirectory.Utils");
MethodInfo mi = asmType.GetMethod("GetDNComponents", BindingFlags.NonPublic | BindingFlags.Static);
string[] parameters = { dn };
var test = mi.Invoke(null, parameters);
//test.Dump("test1");//shows details when using Linqpad
//Convert Distinguished Name (DN) to Relative Distinguished Names (RDN)
MethodInfo mi2 = asmType.GetMethod("GetRdnFromDN", BindingFlags.NonPublic | BindingFlags.Static);
var test2 = mi2.Invoke(null, parameters);
//test2.Dump("test2");//shows details when using Linqpad
Run Code Online (Sandbox Code Playgroud)
结果将如下所示:
//test1 is array of internal "Component" struct that has name/values as strings
Name Value
CN TestGroup
OU Groups
OU UT-SLC
OU US
DC company
DC com
//test2 is a string with CN=RDN
CN=TestGroup
Run Code Online (Sandbox Code Playgroud)
请注意,这不是内部实用程序类,在将来的发行版中可能会更改。
当我找到你的时候,我自己也有同样的问题.在BCL没找到任何东西; 然而,我偶然发现了这篇CodeProject的文章,该文章正好击中了头部.
我希望它也会帮助你.
http://www.codeproject.com/Articles/9788/An-RFC-2253-Compliant-Distinguished-Name-Parser
如果您使用的是 Windows,@MaxKiselev 的答案非常有效。在非 Windows 平台上,它返回每个属性的 ASN1 转储。
.Net Core 5+ 包含 ASN1 解析器,因此您可以使用 .Net Core 以跨平台方式访问 RDN AsnReader
。
辅助类:
public static class X509DistinguishedNameExtensions
{
public static IEnumerable<KeyValuePair<string, string>> GetRelativeNames(this X500DistinguishedName dn)
{
var reader = new AsnReader(dn.RawData, AsnEncodingRules.BER);
var snSeq = reader.ReadSequence();
if (!snSeq.HasData)
{
throw new InvalidOperationException();
}
// Many types are allowable. We're only going to support the string-like ones
// (This excludes IPAddress, X400 address, and other wierd stuff)
// https://www.rfc-editor.org/rfc/rfc5280#page-37
// https://www.rfc-editor.org/rfc/rfc5280#page-112
var allowedRdnTags = new[]
{
UniversalTagNumber.TeletexString, UniversalTagNumber.PrintableString,
UniversalTagNumber.UniversalString, UniversalTagNumber.UTF8String,
UniversalTagNumber.BMPString, UniversalTagNumber.IA5String,
UniversalTagNumber.NumericString, UniversalTagNumber.VisibleString,
UniversalTagNumber.T61String
};
while (snSeq.HasData)
{
var rdnSeq = snSeq.ReadSetOf().ReadSequence();
var attrOid = rdnSeq.ReadObjectIdentifier();
var attrValueTagNo = (UniversalTagNumber)rdnSeq.PeekTag().TagValue;
if (!allowedRdnTags.Contains(attrValueTagNo))
{
throw new NotSupportedException($"Unknown tag type {attrValueTagNo} for attr {attrOid}");
}
var attrValue = rdnSeq.ReadCharacterString(attrValueTagNo);
var friendlyName = new Oid(attrOid).FriendlyName;
yield return new KeyValuePair<string, string>(friendlyName ?? attrOid, attrValue);
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
// Subject: CN=Example, O=Organization
var cert = new X509Certificate2("foo.cer");
var names = this.cert.SubjectName.GetRelativeNames().ToArray();
// names has [ { "CN": "Example" }, { "O": "Organization" } ]
Run Code Online (Sandbox Code Playgroud)
由于这不涉及任何字符串解析,因此不会错误处理转义或注入。它不支持解码包含非字符串元素的 DN,但这些似乎非常罕见。
Win32 函数算吗?您可以将 PInvoke 与DsGetRdnW
. 有关代码,请参阅我对另一个问题的回答: https: //stackoverflow.com/a/11091804/628981。
您可以使用 AsnEncodedData 类从 ASN.1 编码的专有名称中提取通用名称:
var distinguishedName= new X500DistinguishedName("CN=TestGroup,OU=Groups,OU=UT-SLC,OU=US,DC=Company,DC=com");
var commonNameData = new AsnEncodedData("CN", distinguishedName.RawData);
var commonName = commonNameData.Format(false);
Run Code Online (Sandbox Code Playgroud)
此方法的缺点是,如果您指定无法识别的 OID 或专有名称中缺少用 OID 标识的字段,Format
方法将返回一个十六进制字符串,其中包含完整专有名称的编码值,因此您可能需要验证结果。
此外,文档似乎没有指定 AsnEncodedData 构造函数的 rawData 参数是否允许包含除了指定为第一个参数的 OID 之外的其他 OID,因此它可能会在非 Windows 操作系统或未来版本的 .NET Framework 中中断。
您不能只检索 CN 属性值吗?
正如您正确地注意到的那样,请使用其他人的类,因为有很多有趣的边缘情况(转义逗号、转义其他字符)使得解析 DN 看起来很容易,但实际上相当棘手。
我通常使用 Novell(现在的 NetID)身份管理器附带的 Java 类。所以这没有帮助。
归档时间: |
|
查看次数: |
16720 次 |
最近记录: |