这确实是最终由KeyManager
(通常从KeyManagerFactory
).
密钥库可以有多个以不同别名存储的证书。如果没有通过显式配置别名certAlias在码头配置中 http://wiki.eclipse.org/Jetty/Howto/Configure_SSL, the SunX509
实现将选择它找到的第一个别名,其中有一个私钥和一个适合所选密码套件的正确类型的密钥(通常是 RSA,但在您的情况下可能是 DSA)。如果您查看一下,选择逻辑还有更多内容Sun 提供商实施 http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/security/ssl/X509KeyManagerImpl.java#X509KeyManagerImpl.chooseAlias%28java.util.List,java.security.Principal%5B%5D,sun.security.ssl.X509KeyManagerImpl.CheckType%29,但一般来说您不应该真正依赖顺序,而只依赖别名。
您当然可以给 Jetty 自己的SSLContext
与你自己的X509KeyManager http://docs.oracle.com/javase/7/docs/api/javax/net/ssl/X509KeyManager.html选择别名。你必须实施:
chooseServerAlias(String keyType, Principal[] issuers, Socket socket)
不幸的是,除了keyType
and issuers
,你要做的决定就是socket
本身。最好的情况是,您获得的有用信息是本地 IP 地址和远程 IP 地址。
除非您的服务器在同一端口上侦听多个 IP 地址,否则您将始终获得相同的本地 IP 地址。 (在这里,显然,你至少有两个:127.0.0.1
and 192.168.222.100
,但我怀疑除了您自己的测试之外,您对 localhost 并不真正感兴趣。)您需要服务器端的服务器名称指示(SNI)支持,以便能够根据请求的主机名(由客户端支持一下)。很遗憾,SNI仅在Java 7中引入,但仅在客户端 http://docs.oracle.com/javase/7/docs/technotes/guides/security/enhancements7.html.
您在这里将面临的另一个问题是Java 客户端会抱怨主题 DN 的 CN 中的 IP 地址 https://stackoverflow.com/a/8444863/372643。某些浏览器可以容忍这种情况,但这不符合 HTTPS 规范 (RFC 2818)。 IP 地址必须是 IP 地址类型的主题备用名称条目。