首先让我说这是一个美学问题.我已经解决了自己的问题,我只是对更好的方法感到好奇.
所以,我有一个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可能具有的奇怪功能的麻烦.
您可以使用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)
你可以避免使用'糟糕'的表达方式.如果您已经拥有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)
看起来这工作正常
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)