从专有名称中提取通用名称
.NET 中是否存在从 rfc-2253 编码的专有名称解析 CN 的调用?我知道有一些第三方库可以执行此操作,但如果可能的话,我更愿意使用本机 .NET 库。
字符串编码的 DN 示例
CN=L。 Eagle,O=Sue\,Grabbit 和 Runn,C=GB
CN=杰夫·史密斯,OU=销售,DC=Fabrikam,DC=COM
Is there a call in .NET that parses the CN from a rfc-2253 encoded distinguished name? I know there are some third-party libraries that do this, but I would prefer to use native .NET libraries if possible.
Examples of a string encoded DN
CN=L. Eagle,O=Sue\, Grabbit and Runn,C=GB
CN=Jeff Smith,OU=Sales,DC=Fabrikam,DC=COM
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
如果您使用的是
X509Certificate2
,可以使用一种方法来提取简单名称。简单名称相当于主证书的主题字段中的通用名称 RDN:或者,可以使用
X509NameType.DnsName
检索主题备用名称(如果存在);否则,它将默认为通用名称:If you are working with an
X509Certificate2
, there is a method that you can use to extract the Simple Name. The Simple Name is equivalent to the Common Name RDN within the Subject field of the main certificate:Alternatively,
X509NameType.DnsName
can be used to retrieve the Subject Alternative Name, if present; otherwise, it will default to the Common Name:在深入研究 .NET 源代码后,似乎有一个内部实用程序类可以将专有名称解析为不同的组件。不幸的是,该实用程序类并未公开,但您可以使用反射来访问它:
结果将如下所示:
请注意,这是一个内部实用程序类,可能会在将来的版本中更改。
After digging around in the .NET source code it looks like there is an internal utility class that can parse Distinguished Names into their different components. Unfortunately the utility class is not made public, but you can access it using reflection:
The results would look like this:
Please not this is an internal utility class and could change in a future release.
当我找到你的问题时,我自己也有同样的问题。在 BCL 中没有找到任何内容;然而,我确实偶然发现了这篇 CodeProject 文章,它一语中的。
我希望它也能帮助你。
http://www.codeproject.com/Articles /9788/An-RFC-2253-Compliant-Distinguished-Name-Parser
I had the same question, myself, when I found yours. Didn't find anything in the BCL; however, I did stumble across this CodeProject article that hit the nail squarely on the head.
I hope it helps you out, too.
http://www.codeproject.com/Articles/9788/An-RFC-2253-Compliant-Distinguished-Name-Parser
如果您使用的是 Windows,@MaxKiselev 的答案 效果很好。在非 Windows 平台上,它返回每个属性的 ASN1 转储。
.Net Core 5+ 包含 ASN1 解析器,因此您可以使用
AsnReader
以跨平台方式访问 RDN。Helper 类:
用法示例:
由于这不涉及任何字符串解析,因此不会错误处理转义或注入。它不支持解码包含非字符串元素的 DN,但这些似乎非常罕见。
If you are on Windows, @MaxKiselev's answer works perfectly. On non-Windows platforms, it returns the ASN1 dumps of each attribute.
.Net Core 5+ includes an ASN1 parser, so you can access the RDN's in a cross-platform manner by using
AsnReader
.Helper class:
Example usage:
Since this does not involve any string parsing, no escape or injections can be mishandled. It doesn't support decoding DN's that contain non-string elements, but those seem exceedingly rare.
您可以使用 AsnEncodedData 类从 ASN.1 编码的专有名称中提取通用名称:
此方法的缺点是,如果您指定无法识别的 OID 或专有名称中缺少用 OID 标识的字段,
Format
方法将返回一个十六进制字符串,其中包含完整可分辨名称的编码值,因此您可能需要验证结果。此外,文档似乎没有指定 AsnEncodedData 构造函数的 rawData 参数是否允许包含除指定为第一个参数之外的其他 OID,因此它可能会在非 Windows 操作系统或未来版本的 .NET Framework 中中断。
You can extract the common name from an ASN.1-encoded distinguished name using AsnEncodedData class:
A downside of this approach is that if you specify an unrecognized OID or the field identified with the OID is missing in the distinguished name,
Format
method will return a hex string with the encoded value of full distinguished name so you may want to verify the result.Also the documentation does not seem to specify if the rawData parameter of the AsnEncodedData constructor is allowed to contain other OIDs besides the one specified as the first argument so it may break on non-Windows OS or in a future version of .NET Framework.
Win32 函数算吗?您可以将 PInvoke 与
DsGetRdnW
。有关代码,请参阅我对另一个问题的回答:https://stackoverflow.com/a/11091804/628981。Do Win32 functions count? You can use PInvoke with
DsGetRdnW
. For code, see my answer to another question: https://stackoverflow.com/a/11091804/628981.只是在这里添加我的两分钱。如果您首先了解哪些业务规则将最终决定您公司将实施多少 RFC,则此实施效果“最佳”。
Just adding my two cents here. This implementation works "best" if you first learn what business rules are in place that will ultimately dictate how much of the RFC will ever be implemented at your company.
这个怎么样:
改编自 用于提取活动部分的 Powershell 正则表达式目录专有名称。
How about this one:
Adapted from Powershell Regular Expression for Extracting Parts of an Active Directory Distiniguished Name.
您可以使用正则表达式来执行此操作。这是一个可以解析整个 DN 的正则表达式模式,然后您可以只获取您感兴趣的部分:
(?:^|,\s?)(?:(?[AZ]+) =(?"(?:[^"]|"")+"|(?:\\,|[^,])+))+
这里它的格式更好一点,并附上一些评论:
这regex 将为您提供每个匹配的
name
和val
捕获组,可以选择引用 DN 字符串(例如
"Hello"
,这允许它们包含未转义的逗号。或者,如果未加引号,则必须使用反斜杠转义逗号(例如Hello\,there!
)。这里有一个链接,以便您可以查看它 。行动中: https://regex101.com/r/7vhdDz/1
You could use regular expressions to do this. Here's a regex pattern than can parse the whole DN, then you can just take the parts you are interested in:
(?:^|,\s?)(?:(?<name>[A-Z]+)=(?<val>"(?:[^"]|"")+"|(?:\\,|[^,])+))+
Here it is formatted a bit nicer, and with some comments:
This regex will give you
name
andval
capture groups for each match.DN strings can optionally be quoted (e.g.
"Hello"
, which allows them to contain unescaped commas. Alternatively, if not quoted, commas must be escaped with a backslash (e.g.Hello\, there!
). This regex handles both quoted and unquoted strings.Here's a link so you can see it in action: https://regex101.com/r/7vhdDz/1
如果顺序不确定,我会这样做:
If the order is uncertain, I do this:
这是我的几乎符合 RFC 标准的故障安全 DN 解析器,源自 https://www.codeproject.com/Articles/9788/An-RFC-2253-Compliant-Distinguished-Name-Parser 及其用法示例(提取主题名称为 CN 和 O,两者可选,用逗号连接):
This is my almost RFC-compliant fail-safe DN parser derived from https://www.codeproject.com/Articles/9788/An-RFC-2253-Compliant-Distinguished-Name-Parser and an example of its usage (extract subject name as CN and O, both optional, concatenated with comma):
抱歉来晚了一点,但我能够直接从 c# 调用 Name 属性
,然后我能够调用
,这给了我全名(通用名)
示例代码:
显然,您必须填写在空白处。但这应该比解析正则表达式更容易。
Sorry for being a bit late to the party, but I was able to call the Name attribute directly from c#
and then I was able to call
and that gave me the full name (Common Name)
Sample code:
Obviously, you will have to fill in the blanks. But this should be easier than parsing regex.
您不能只检索 CN 属性值吗?
正如您正确地注意到的那样,请使用其他人的类,因为有很多有趣的边缘情况(转义逗号、转义其他字符)使得解析 DN 看起来很容易,但实际上相当棘手。
我通常使用 Novell(现在的 NetID)身份管理器附带的 Java 类。所以这没有帮助。
Could you not just retrieve the CN attribute values?
As you correctly note, use someone else's class as there are lots of fun edge cases (escaped commas, escaped other characters) that make parsing a DN look easy, but actually reasonably tricky.
I usually use a Java class that comes with the Novell (Now NetID) Identity Manager. So that is not helpful.
好吧,我又是一个迟到的人。这是我的解决方案:
基本上它利用 X500DistinguishedName.Format 方法将内容放在线上。然后按行拆分,然后将每一行拆分为键值。
Well, Here I am another person late to the party. Here is my Solution:
Basically its leveraging the X500DistinguishedName.Format method to put things on lines. Then split by lines, then split each line into key value.