为什么Nginx以相反的顺序提供客户端SSL DN?

我很好奇为什么一些networking服务器(例如Nginx)以相反的顺序提供客户端SSL DN。

Web应用程序将DN发布到正在尝试创buildJava javax.naming.ldap.LdapName的Java Web Service。

标准订单(LDAP或X500Name):

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

反序(OpenSSL Oneline格式)(Nginx返回为_ $ ssl_client_s_dn_):

 "/DC=Bloopsoft-Inc/OU=Employees/OU=Someplace/CN=Jimmy Blooptoop" 

为什么是这样?

哪一个匹配LDAP RFC?

他们都是?

LDAP RFC注释:

有许多与LDAP相关的RFC: https : //www.ldap.com/ldap-specifications-defined-in-rfcs

许多人提到不同的东西,这里有一个很快的尝试:

  • 1993年7月:RFC 1485 – 可分辨名称的string表示
  • 1995年3月:RFC 1779 – 可分辨名称的string表示
  • Dec 1997:RFC 2253 – 轻量级目录访问协议(v3):可分辨名称的UTF-8string表示
  • 2002年9月:RFC 3377 – 轻量级目录访问协议(v3):技术规范(更新RFC 2253)
  • 2003年3月:RFC 3494 – 轻量级目录访问协议版本2(LDAPv2)到历史状态(Retiring RFC 1485,RFC 1779)
  • 2006年6月:RFC 4514 – 轻量级目录访问协议(LDAP):可分辨名称的string表示

最近的一个,它已经过时了: RFC 4514:轻量级目录访问协议(LDAP):string表示的专有名称

Java库:

是否有Java库来回转换(从反转到不反转)? LdapName引发一个InvalidNameException。 似乎应该有,倒退格式频繁出现。

Java库:

  • javax.naming.ldap.LdapName支持RFC 2253
  • org.apache.directory.api.ldap.model.filter.FilterEncoder支持RFC 4514
  • Spring LdapUtils包装LdapName
  • 关于使用BouncyCastle X509Nameparsing和编译DN的文章: http : //www.sivachandran.in/2012/11/comparing-x509-distinguished-name-with.html

Ngninx备注:

  • http://nginx.org/en/docs/http/ngx_http_ssl_module.html

链接:

  • 如何在Java中从X509Certificate中提取CN?
  • 从证书DNparsingCN (借用的DN示例)
  • Nginx的信息
  • X500Principal可分辨名称顺序
  • https://wiki.nikhef.nl/grid/How_to_handle_OpenSSL_and_not_get_hurt_background_information
  • https://www.openssl.org/docs/manmaster/apps/x509.html#item_oneline

为什么是这样?

这是因为这是OpenSSL返回的。 Apache HTTPD做同样的事情,因为它也使用OpenSSL。

哪一个匹配LDAP RFC?

你称之为“标准订单”的那个。 但是,这是一个SSL证书和一个SSL API。 它与LDAP没有任何关系,没有理由要符合任何LDAP RFC。 这只是提供证书主题的DN的另一种方式。 这是由X.509定义的,而不是由LDAP定义的(尽管最终它们都是由X.500定义的,至少原来是这样定义的)。

有没有Java库来回转换(从反转到不反转)

关注话题,而不是我所知道的,但写起来很容易:

 public class OpenSSLSubjectName { private String name; public OpenSSLSubjectName(String name) { this.name = name; } public String getX500Name() throws NamingException { return getLdapName().toString(); } public LdapName getLdapName() throws NamingException { List<Rdn> rdns = new LinkedList<>(); String[] parts = name.split("/"); for (int i = 1; i < parts.length; i++) { rdns.add(new Rdn(parts[i])); } return new LdapName(rdns); } } 

E&OE