Java MTLS主题和颁发者顺序

时间:2019-10-02 20:06:13

标签: java ssl mtls

我们正在升级自己与合作伙伴之间的连接,他们要求我们升级到MTLS。我一直在调试底层Java

javax.net.debug=all 我可以看到握手成功。但是,合作伙伴会与“主题”和“发行者”字段进行完整的字符串匹配,并与他们数据库中的某些字段进行比较。

我已经使用了以下内容,

   if (cert instanceof X509Certificate) {
        X509Certificate x509cert = (X509Certificate) cert;

        // Get subject
        Principal principal = x509cert.getSubjectDN();
        String subjectDn = principal.getName();
        logger.error(subjectDn);
        // Get issuer
        principal = x509cert.getIssuerDN();
        String issuerDn = principal.getName();
        logger.error(issuerDn);
    }

转储Java具有的值。有趣的是,openssl以与Java报告完全不同的顺序报告它们。

我现在已经在Wireshark中进行挖掘,并且可以看到该级别的握手,但是,据我所知,这似乎将名称转换为id-at-commonNamepkcs-9-at-emailAddress。 / p>

有什么办法可以知道实际发送的是什么?

1 个答案:

答案 0 :(得分:1)

没有协议MTLS,但这听起来像是您在关心TLS中的客户端身份验证,也称为相互身份验证,就像服务器身份验证通常使用X.509类型(更确切地说是PKIX)证书一样。

背景:X.509 / PKIX证书使用X.500/501 Distinguished Name structure也称为X500Name,X501Name或简称为Name来标识主题和颁发者(有时在某些扩展名中还包括其他事物/实体)。这种结构在ASN.1中定义为RelativeDistinguishedName项的SEQUENCE(有序),每个项正式都是属性类型和值对(SEQUENCE)的SET(无序),尽管实际上RDN SET几乎总是单例,因此,名称实际上是属性类型和值的序列。此名称格式旨在用于“目录”的全球,分布式,分层的网络中,而不是像DNS ,除了(因为CCITT-now-ITU-T是政府机构的组织)主要基于在基于国家/地区的国家/地区目录中,而不是像.com .org .edu .gov .mil .net这样的功能或“通用”目录中,而X.509证书基本上是从该目录网络中导出的数据,可离线使用。实际上,根本不使用真正的X.500目录,除了Microsoft Windows“域”(活动目录)外,甚至不使用诸如LDAP(轻型目录访问协议)之类的协议,而是使用X.509证书包括其中使用的名称格式在内,已广泛用于SSL-now-TLS,S / MIME和许多其他应用程序。

DN的常规文本或外部形式是一系列attr = value项,其中attr通常被缩写,例如C代表国家,C代表StateOrProvince,CN代表CommonName,等等。Java使用RFC 1485、1779、2253和4514定义的标准格式(有少量更改/改进),其中各项用逗号分隔并在 reverse中给出顺序,即从最后一个(最低级别)到第一个(最高级别通常是根),类似于DNS。例如,Java将www.duckduckgo.com当前使用的证书的主题显示为

CN=*.duckduckgo.com, O="Duck Duck Go, Inc.", L=Paoli, ST=Pennsylvania, C=US
传统上,默认情况下,

OpenSSL默认使用一种格式,在每个项目前加斜杠( )(而不是用逗号分隔( ),并且也以 forward 顺序)

/C=US/ST=Pennsylvania/L=Paoli/O=Duck Duck Go, Inc./CN=*.duckduckgo.com

但是1.1.0向上更改了默认设置,以使用具有向前顺序的逗号分隔符

C = US, ST = Pennsylvania, L = Paoli, O = "Duck Duck Go, Inc.", CN = *.duckduckgo.com 

某些OpenSSL命令行操作,例如x509,支持其他显示格式;请参见“名称选项”下的手册页。特别是x509 -nameopt oneline,dn_rev给出的格式几乎与Java相同:

CN = *.duckduckgo.com, O = "Duck Duck Go, Inc.", L = Paoli, ST = Pennsylvania, C = US

Wireshark,如果仅查看传输证书的 summary (在TLS中),则以RFC和Java的相反顺序显示具有全名的attribute = value对,而不是属性的缩写:

Wireshark unexpanded display

但是,如果您单击加号框以扩展几个级别,则可以按向前的顺序分别看到每个属性项的结构:

Wireshark expanded display

正是由于显示格式存在多种变化,所以将DN作为字符串进行比较并不是一个好主意。如果您需要将其作为字符串存储在例如在数据库中,更好的方法是从字符串中重建结构化形式-使用一致的约定(如顺序,缩写等),然后比较结构化对象。如果您阅读Javadoc并发现X509Certificate.getIssuerDN()和类似的.getSubjectDN()被“贬义了”(显然打算被“弃用”)并从Java 1.4开始被.getIssuerX500Principal()取代了,这会变得容易一些。和.getSubjectX500Principal(),它们使用已记录的API类(而不是不透明的内部类)javax.security.auth.x500.X500Principal和已记录的.equals()操作。

相关问题