从证书DN中解析CN

JDS*_*JDS 26 java regex

首先让我说这是一个美学问题.我已经解决了自己的问题,我只是对更好的方法感到好奇.

所以,我有一个DN证书,如下所示:

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

现在,我想从中获取CN.在java中,除了使用Xoun9证书中的完整DN而没有使用像bouncy castle这样的第三方库时,没有原生支持可以抓取任何东西 - 我无法使用它.所以我必须解析它,这不是什么大问题.唯一让它有点棘手的事实是CN并不总是被格式化为<first name> <last name>.通常情况下,它实际上会是<last name>, <first name> <middle initial>.所以,在上面的例子中,CN可能是Jimmy Blooptoop或Blooptoop,Jimmy J(当然是Joop的缩写).

在阅读了有关正则表达式的内容之后,我写了以下内容,它运作良好:

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

我只是好奇是否有看起来不像垃圾的表情.我非常有信心,因为我在阅读了正则表达式的介绍之后就已经解决了这个问题.

mus*_*iKk 58

怎么样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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这不是最漂亮的界面,因为有一些缺失的东西,LdapName#getByType(String)但它可以省去你必须考虑DN可能具有的奇怪功能的麻烦.

  • 绝对是一个比正则表达式更稳固的解决方案,使用BouncyCastle API是另一种选择,请参阅[如何从java中的x509certificate中提取cn](http://stackoverflow.com/questions/2914521/how-to-extract-cn-从-x509证书-在-java的) (4认同)
  • 稍微好一点的解决方案:for(Rdn rdn:ln.getRdns()){...} (2认同)

Sah*_*bra 7

您可以使用Spring Frameworks LdapUtils以如下所示的整齐方式提取CN:

String cn = LdapUtils.getStringValue(new LdapName(group),"cn");
Run Code Online (Sandbox Code Playgroud)

要么

不使用如下的Spring Framework:

String cn = (String)new LdapName(group).getRdns().stream().filter(rdn -> rdn.getType().equalsIgnoreCase("CN")).findFirst().get().getValue();
Run Code Online (Sandbox Code Playgroud)


Kon*_*kov 6

你可以避免使用'糟糕'的表达方式.如果您已经拥有DN,则可以拆分String,然后找到CN.例如:

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 将失败,例如,"CN = Go Daddy Root Certificate Authority - G2,O ="GoDaddy.com,Inc.",L = Scottsdale,ST = Arizona,C = US` (3认同)
  • 尽管正则表达式有效,但它们通常使用起来很昂贵.对于这样一个简单的字符串格式,逗号分隔,字符串拆分会更好.不幸的是,OP已声明值有时也可能包含逗号,这使得此解决方案无效. (2认同)
  • 在`CN=Development Cyanogen Application,OU=Release Management,O=Cyanogen\, Inc.,L=Seattle,ST=Washington,C=US`上也会失败 (2认同)

Ale*_*x G 5

看起来这工作正常

CertificateFactory fact = CertificateFactory.getInstance("X.509");
FileInputStream is = new FileInputStream ("cert.pem");
X509Certificate cert = (X509Certificate) fact.generateCertificate(is);
String cn = ((X500Name)cert.getSubjectDN()).getCommonName()
Run Code Online (Sandbox Code Playgroud)