当客户端根本没有设置SNI servername时,Java如何 Select 默认/回退服务器证书?

背景:

我用multiple server certificates创建了PKCS#12密钥库.我还使用JKS密钥库进行了测试.我使用X509KeyManagerNewSunX509实现,它可以根据请求的SNI服务器名 Select 匹配的服务器证书.

我找不到JSSE用于 Select 默认或"回退"服务器证书的规则,当客户端在TLS握手中不发送SNI servername时,JSSE将返回该规则.我没有找到文档,也没有通过测试找到答案.实现(code link)表示它对不完美匹配进行排序.实际上, Select 似乎会受到在keystore中添加条目的顺序的影响,但它不会简单地 Select 第一个或最后一个条目,也不会按别名排序,即使代码注释会给人留下这样的印象.

推荐答案

我没有看到任何关于按别名排序的 comments .If不完全匹配排序发生时,它使用EntryStatus.compareTo进行排序,首先是CheckResult(即,证书接近"良好"程度的度量),然后是keyIndex,这是调用者基于SSL/TLS协议请求的keyTypes列表中的位置(即密码套件和/或signature\u算法值,可能是优先顺序).如果两者相等,则Collections.sort是稳定的,因此它将使用测试和发现的顺序,请参阅下一步.

然而,只有当没有"完美"匹配时,才会进行排序;一旦找到任何"完美"匹配,就会返回,而不会寻找可能存在的任何其他匹配.因此,返回哪个取决于查看和测试密钥库条目的顺序.chooseAlias正如你所链接的,它与SNI idalg的sibling 姐妹一样,如果有多个,首先按"构建者"顺序查看,通常不会有;在"构建器"(即密钥库)中,他们调用getAliases,您可以看到,getAliases使用ks.aliases()返回的Enumeration,这由使用的KeyStore个实例决定.

File-based密钥库(如PKCS12和JKS)通常使用由alias键入的Map或更旧的(预集合)Hashtable.尤其是PKCS12使用LinkedHashMap,它以插入的顺序返回密钥/条目,我认为这或多或少就是它们在存储文件中的顺序(虽然在PKCS12中,证书和私钥的顺序可能不同,我不确定是哪个控件),但这不必与别名/名称、创建或其他任何东西的顺序相同.JKS使用Hashtable,它按哈希代码的降序对映射大小进行模化枚举,映射大小主要取决于插入的条目数,如果发生冲突,它将使用链表并按插入的相反顺序返回,除非重新灰化会改变这一点.

对于PKCS11、Windows、Apple等非基于文件的密钥库,可以通过Java接口代码、底层工具提供的内容或组合来确定.

TLDR:就你而言,这是不可预测的,实际上也可能是随机的.如果您关心您得到的是哪一个,可以编写自己的KeyManager逻辑来实现您的 Select (或者使用预先编写的逻辑,如Apache httpcomponents),或者过滤您提供给默认KeyManager的密钥库中的数据.

同样需要明确的是,这仅适用于您指定的NewSunX509.default键管理器(仍然!)更老的SunX509和工作方式不同;它有own个HashMap来控制迭代,而不是使用底层keystore的HashMap.(单数,因为SunX509只取一个.)

Java相关问答推荐

一般类型和kotlin阴影Java函数的问题

Java 8 RDX-如何设置单个选项卡标题文本的 colored颜色

如何从片段请求数据到活动?在主要活动中单击按钮请求数据?

当耗时的代码完成时,Circular ProgressIndicator显示得太晚

使用Apache Poi MQLSlideShow,在XSLFTable表中,我们可以在文本段落后面的每个单元格中包含圆角矩形吗?

多个Java线程和TreeMap.put()的非预期行为

Java Swing:初始化身份验证类后未检测到ATM_Interface键事件

Java记录的不同序列化/反序列化

编译多个.Java文件并运行一个依赖于用户参数的文件

第三方Jar pom.xml

Java Mooc.fi Part 12_01.Hideout -返回和删除方法

虚拟线程应该很快消亡吗?

有效的公式或值列表必须少于或等于255个字符

错误:未找到扩展元素在JBossEAP 7.2中安装FUSE时出错

具有多个模式的DateTimeForMatter的LocalDate.parse失败

Win32函数的JNA绑定DwmGetColorizationColor返回E_INVALIDARG错误

不能在 map 上移除折线

ReturnedRect在升级后反转

当我try 返回可选时,Mock无法正常工作

可以';不要在Intellij IDEA中使用最新的Java版本(JDK 21)