Parsing CN from DN Certificate

Let me start by saying that this is a matter of aesthetics. I solved my problem, I'm just wondering how to do it.

So, I have a certificate DN, something like this:

CN = Jimmy Blooptoop, OU = Someplace, OU = Employees, DC = Bloopsoft-Inc

Now I want to grab CN from this. There is no built-in support in Java for capturing everything except the full DN from an X509 certificate, without using any third-party library such as bouncy castle - which I cannot use. Therefore, I have to make it out, that there are not many problems. The only thing that confuses a bit is that CN will not always be formatted as <first name> <last name> . Most often it will be <last name>, <first name> <middle initial> . So, in the above example, CN can be Jimmy Bluptop or Bluptotop, Jimmy J (of course, for Joop).

After viewing and regexing, I wrote the following, which works quite well:

 Matcher m = Pattern.compile("CN=[A-Za-z]*[, ]*[ A-Za-z]*").matcher(dn); if (m.find()) cn = m.group(); 

I'm just wondering if there are expressions that would look smaller than shit. I'm pretty sure there is, since I worked on this after reading only the introduction to the regex.

+21
java regex
Oct 28 '11 at 18:45
source share
9 answers

What about javax.naming.ldap.LdapName ?

 String dn = "CN=Jimmy Blooptoop,OU=Someplace,OU=Employees,DC=Bloopsoft-Inc"; LdapName ln = new LdapName(dn); for(Rdn rdn : ln.getRdns()) { if(rdn.getType().equalsIgnoreCase("CN")) { System.err.println("CN is: " + rdn.getValue()); break; } } 

This is not the most beautiful interface, since there is something missing, for example LdapName#getByType(String) , but this saves you from having to think about what strange functions might have in DNs.

+46
Oct 28 '11 at 19:04
source share

You can avoid using the expression 'crappy'. If you already have a DN, you can split the String and then find the CN. For example:

 String dn = "CN=Jimmy Blooptoop,OU=Someplace,OU=Employees,DC=Bloopsoft-Inc"; String[] split = dn.split(","); for (String x : split) { if (x.contains("CN=")) { System.out.println(x.trim()); } } 
+5
Oct 28 '11 at 18:53
source share

If you are using Spring Framework, you can use DistinguishedName as follows:

 String path = "CN=Jimmy Blooptoop,OU=Someplace,OU=Employees,DC=Bloopsoft-Inc"; DistinguishedName dn = new DistinguishedName(path); String cn = dn.getValue("cn"); // Jimmy Blooptoop 
+4
Feb 03 '15 at 3:56
source share

You should not use the regular expressions suggested above. The problem with these regular expressions is that you will not follow RFC 4514 and will not ignore previously escaped characters and may potentially lose or misinterpret the distinguished name. Use the LdapName class, as recommended by musiKk , to parse the distinguished name correctly.

+2
May 28 '13 at 5:11
source share

You can use Spring Frameworks LdapUtils to extract CN in a neat way, as shown below:

 String cn = LdapUtils.getStringValue(new LdapName(group),"cn"); 

OR

Without using the Spring Framework as shown below:

 String cn = (String)new LdapName(group).getRdns().stream().filter(rdn -> rdn.getType().equalsIgnoreCase("CN")).findFirst().get().getValue(); 
+1
Nov 29 '17 at 6:59
source share

It looks like it works ok

 CertificateFactory fact = CertificateFactory.getInstance("X.509"); FileInputStream is = new FileInputStream ("cert.pem"); X509Certificate cert = (X509Certificate) fact.generateCertificate(is); String cn = ((X500Name)cert.getSubjectDN()).getCommonName() 
0
Jun 16 '17 at 13:41 on
source share

If I understood correctly, this should lead to the same result, it just looks a little more readable. \w matches any character of a word.

 "CN=[\\w]*[., ]+[\\w ]*" 

If you want something more flexible, you can do this:

 Matcher m = Pattern.compile("(CN=.*?),[AZ]{2}=").matcher(dn); if (m.find()) cn = m.group(1); 

This corresponds to something between "CN =" and ", XX =", where XX are two capital letters. group(1) returns the first group (match inside parentheses).

Regexp is not as hard as they look!

-one
Oct 28 '11 at 19:11
source share

I parse a DN like this. You get all the attributes as properties:

 Principal principal = cert.getSubjectDN(); Properties prop = new Properties(); prop.load(new StringReader(principal.getName().replaceAll(",", "\n"))); prop.list(System.out); String CN= props.get("CN"); 

It does not work for duplicate elements like ou or dc.

-one
May 21 '12 at 13:14
source share

Regular expressions are quite expensive to use. For such a simple task, this is likely to be more than killing. Instead, you can use simple line breaks:

 String dn = ((X509Certificate) certificate).getIssuerDN().getName(); String CN = getValByAttributeTypeFromIssuerDN(dn,"CN="); private String getValByAttributeTypeFromIssuerDN(String dn, String attributeType) { String[] dnSplits = dn.split(","); for (String dnSplit : dnSplits) { if (dnSplit.contains(attributeType)) { String[] cnSplits = dnSplit.trim().split("="); if(cnSplits[1]!= null) { return cnSplits[1].trim(); } } } return ""; } 
-one
Jul 24 '14 at 12:36 on
source share



All Articles