我们的应用程序需要一个数据,它包含在客户端证书的通用名称中。目前,我正试图从HttpContext.Current.Request.ClientCertificate获取它。我怎么读出来的?可悲的是,我正在尝试对这个盲人进行编码,同时我弄清楚为什么SoapUI没有发送证书,所以除了阅读有关MSDN上的对象并探索空属性之外,我没有尝试过多,但我不确定我正在寻找什么。那么回顾一下,我需要做些什么来从这个证书中提取通用名称? TIA
答案 0 :(得分:7)
我可能为时已晚,无法回答您的问题,但我希望这有助于其他寻求从证书中获取通用名称的方式。
如果使用“主题”,则可能需要删除其他不必要的信息。 例如,CN = localhost,OU = DepartmentName,O = CompanyName,L = Location,S = State,C = Country
Dim store As New X509Store(StoreName.My, StoreLocation.LocalMachine)
store.Open(OpenFlags.ReadOnly)
store.Certificates(0).Subject
但是如果您使用下面的代码,您将获得'localhost',它直接为您提供证书的通用名称。
Dim store As New X509Store(StoreName.My, StoreLocation.LocalMachine)
store.Open(OpenFlags.ReadOnly)
store.Certificates(0).GetNameInfo(X509NameType.SimpleName, False)
答案 1 :(得分:5)
我对证书知之甚少。这是我的工作流程:
我开始于:
导致我:
HttpClientCertificate(作为返回类型)。
它似乎有一些属性,但没有明确命名为通用名称。
Google搜索:HttpClientCertificate通用名称:
Problem with extracting X509 certificate from Context on web service side
其中有一些代码:
//extracting Common name from certificate
Subject = cert.Subject.ToString();
然后去了:
备注:
如果指定的String没有子字段,则HttpClientCertificate集合返回以逗号分隔的子字段列表。例如,C = US,O = Msft。
由于我的知识极其有限,我知道 Common Name = 在此列表中。目前我没有实际的方法来测试这个,但是要解析你想要的名称这个值应该不难。
这是一个很好的问题(+1),我很高兴你问它,因为它可能对未来的读者有用。
我创建了一个DotNetFiddle Example,即使它使用HttpWebRequest来获取X509Certificate类,它也有一个Subject属性,它在www.google.com上为https返回了以下值:
CN = www.google.com,O = Google Inc,L = Mountain View,S = California,C = US
所以我倾向于相信HttpClientCertificate上的Subject将是相同的值(知道CN意味着CommonName)。
答案 2 :(得分:1)
由于证书格式的差异,您可能需要进行调整。
以下是一些代码:
HttpClientCertificate theHttpCertificate = HttpContext.Current.Request.ClientCertificate;
// split the subject into its parts
string[] subjectArray = theHttpCertificate.Subject.Split(',');
string[] nameParts;
string CN = string.Empty;
string firstName = string.Empty;
string lastName = string.Empty;
foreach (string item in subjectArray)
{
string[] oneItem = item.Split('=');
// Split the Subject CN information
if (oneItem[0].Trim() == "CN")
{
CN = oneItem[1];
if (CN.IndexOf(".") > 0)
{// Split the name information
nameParts = CN.Split('.');
lastName = nameParts[0];
firstName = nameParts[1];
}
}
}
答案 3 :(得分:1)
只是Linq的一个oneliner。
var kvs = cert.Subject.Split(',').Select(x => new KeyValuePair<string, string>(x.Split('=')[0], x.Split('=')[1])).ToList();
返回通用列表。不要在这里使用字典,因为Subject可以包含重复的字段。
答案 4 :(得分:0)
最好的做法是使用使用名称类型和布尔标志的内置 GetNameInfo 方法
假设您使用此扩展方法:
[return:MaybeNull]
public static X509Certificate2? GetCodeSignCertificate(this Assembly asm)
{
if (asm is null)
{
throw new ArgumentNullException(nameof(asm));
}
if (!File.Exists(asm.Location))
{
return null;
}
using var cert=System.Security.Cryptography.X509Certificates.X509Certificate.CreateFromSignedFile(asm.Location);
if (cert is null)
return null;
return new X509Certificate2(cert);
}
然后您可以使用类中的类型来获取证书,如下所示:
[TestMethod()]
public void TryGetCodeSigning()
{
//var item = new Walter.CallStack();
var item = new List<string>();
using var cert = item.GetType().Assembly.GetCodeSignCertificate();
Assert.IsNotNull(cert.GetNameInfo(X509NameType.SimpleName,true));
}
获取证书签名机构的名称
cert.GetNameInfo(X509NameType.SimpleName,true)
获取证书签署人的姓名
cert.GetNameInfo(X509NameType.SimpleName,false)
看看 X509NameType 是否适合您。