1

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

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

我用过以下,

   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

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

4

1 回答 1

3

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

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

DN 的常规文本或外部形式是一系列 attr=value 项,其中 attr 通常是缩写,例如 C 代表 Country,ST 代表 StateOrProvince,CN 代表 CommonName 等。Java 使用定义的标准化形式(稍作改动/improvements) 由 RFC 1485、1779、2253 和 4514 提供,其中项目以逗号分隔并以相反的顺序给出,即从最后一个(最低级别)到第一个(最高级别通常是根),类似于 DNS。例如,Java 将www.duckduckgo.com当前使用的证书的主题显示为

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

OpenSSL 传统上默认使用在每个项目前带有斜杠的格式(而不是逗号分隔它们),并且也按序排列

/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

如果您只查看传输证书的摘要(在 TLS 中),Wireshark 会显示属性=值对,其中包含全名而不是属性的缩写,其顺序与 RFC 和 Java 一样:

Wireshark 未扩展显示

但是,如果您单击加号框以展开几个级别,您可以分别查看每个属性项的结构,按正序排列:

Wireshark 扩展显示

正是因为显示格式有很多变化,所以将 DN 作为字符串进行比较并不是一个好主意。如果您需要将其作为字符串存储在例如数据库中,更好的方法是从字符串重建结构化形式——使用一致的顺序、缩写等约定——并比较结构化对象。如果您阅读 javadoc 并看到X509Certificate.getIssuerDN()类似地.getSubjectDN()被“贬低”(显然打算被“弃用”)并自 Java 1.4 起被使用文档化的 API 类(而不是不透明的内部类)取代.getIssuerX500Principal(),这会变得更容易一些有记录的操作。.getSubjectX500Principal()javax.security.auth.x500.X500Principal.equals()

于 2019-10-03T23:43:06.447 回答