I have a RemoteCertificateValidationCallback function called by SslStream.AuthenticateAsClient, which is passed an X509Certificate object.
I'd like to extract the name from that certificate, such that had I passed that string into AuthenticateAsClient, it would have passed. (Assuming no other issues.)
(Note: The Subject property contains the domain name, but it's inside a "CN=..., S=..." etc formatted string.)
See also: How to extract CN from X509Certificate in Java? (Asks a similar question for Java, but I can't find similar classes for .NET mentioned in those answers.)
(Followup to Eugene's answer.)
I've tried this...
var cert2 = new System.Security.Cryptography.X509Certificates.X509Certificate2();
cert2.Import(certificate.GetRawCertData());
... but cert2.SubjectName.Name still has the CN= etc formatting. Am I doing it wrong?
I have done it the following way:
var cert2 = new X509Certificate2(cert);
string hostName = cert2.GetNameInfo(X509NameType.DnsName, false);
You may also check whether the certificate is valid:
bool valid = cert2.Verify();
(See this question for description of X509Certificate2 class)
For my certificate strings it worked better with a small adjustment like this
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();
Use GetRawCertData method to get Certificate's DER data. Then create an instance of X509Certificate2 object and load the raw cert data using Import() method. Then use SubjectName property to access individual subject fields. Note - you also need to inspect Subject Alternative Name extension, but unfortunately there's no easy way to do this in .NET Framework classes (you might find it necessary to use third-party PKI library for proper certificate validation and management).
I used the following method to parse strings returned from AD, it may help parse the data your recieving:
/// <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;
}
So give it a string like "CN=my common name,CN=another common name,O=my orginization" and it will return a list containing both common names.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With