为了账号安全,请及时绑定邮箱和手机立即绑定

Java MTLS 主题和发行者顺序

Java MTLS 主题和发行者顺序

翻阅古今 2023-09-20 19:05:44
我们正在升级我们自己和合作伙伴之间的连接,他们要求我们升级到 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-commonName,它似乎将名称翻译为。pkcs-9-at-emailAddress有什么办法可以知道实际发送的内容是什么?
查看完整描述

1 回答

?
达令说

TA贡献1821条经验 获得超6个赞

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

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

DN 的常规文本或外部形式是一系列 attr=value 项,其中 attr 通常是缩写,例如 C 代表国家/地区、ST 代表州或省、CN 代表 CommonName 等。Java 使用定义的标准化形式(有一些小的变化) /improvements)由 RFC 1485、1779、2253 和 4514 制定,其中项目以逗号分隔并按相反顺序给出,即从最后一个(最低级别)到第一个(最高级别通常为根),类似于 DNS。

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 将显示带有全名的 attribute=value 对,而不是属性的缩写,与 RFC 和 Java 一样,按相反的顺序:

https://img1.sycdn.imooc.com/650ad2390001f15806520644.jpg

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

https://img1.sycdn.imooc.com/650ad24300014aa806530645.jpg

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


查看完整回答
反对 回复 2023-09-20
  • 1 回答
  • 0 关注
  • 69 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信