Pyv*_*ves 5 java ssl netty reactor-netty
我需要查询证书/DNS 名称不匹配的第三方 API。证书中指定的主机名的最左侧标签事先未知(即CN=some-random-hash.example.com),因此我想使用自定义主机名验证器配置 HTTP 客户端。
当使用通过 获取的默认Reactor NettyHttpClient.create()客户端时,HostnameChecker类会失败证书验证并导致抛出异常:
java.security.cert.CertificateException: No subject alternative DNS name matching XXX found.
at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:214)
at sun.security.util.HostnameChecker.match(HostnameChecker.java:96)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:436)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:252)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:136)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1626)
... 30 more
Run Code Online (Sandbox Code Playgroud)
这个相关答案建议按如下方式实现 SNIMatcher:
HttpClient.create()
.secure(sslContextSpec -> sslContextSpec
.sslContext(sslContext)
.handlerConfigurator((handler) -> {
SSLEngine engine = handler.engine();
SSLParameters params = new SSLParameters();
List<SNIMatcher> matchers = new LinkedList<>();
SNIMatcher matcher = new SNIMatcher(0) {
@Override
public boolean matches(SNIServerName serverName) {
return true;
}
};
matchers.add(matcher);
params.setSNIMatchers(matchers);
engine.setSSLParameters(params);
}));
Run Code Online (Sandbox Code Playgroud)
然而,根据setSNIMatchers 的 Javadocs:
此方法仅对在服务器模式下运行的 SSLSocket 或 SSLEngine 有用。
因此,匹配器被忽略,更糟糕的是,上面的代码创建了一个空集SSLParameters,这似乎完全禁用了 SSL 验证。
如何使用Reactor Netty正确实现自定义主机名验证器?
请注意,当使用Apache HTTPClient库时,可以通过以下方式轻松实现:
HttpClients.custom().setSSLHostnameVerifier((hostname, session) -> ...).build();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
897 次 |
| 最近记录: |