使用IBMJSSE2默认提供者时如何从SSLContext获取全部TLS会话
根因说明
WebSphere 8.5自带的IBMJSSEProvider2默认启用了独立的SSL上下文隔离机制,应用发起的HTTPS连接使用的是WebSphere为当前应用/安全域分配的专有SSLContext,不会将会话同步到JVM全局默认的SSLContext.getDefault()实例中,同时默认关闭了全局客户端会话缓存,所以原来的代码拿不到RestTemplate产生的会话信息。
解决方案
方案1:修改全局JSSE配置(无需改代码)
登录WebSphere管理控制台,按以下路径调整配置:
- 进入
安全 > SSL证书和密钥管理 > 相关项 > JSSE提供程序 - 选中正在使用的
IBMJSSEProvider2,点击「自定义属性」,添加以下属性:com.ibm.jsse2.spi.session.cache.enable:值设为true,开启全局会话缓存com.ibm.jsse2.sslSessionContext.share:值设为true,允许全局会话上下文同步所有应用的TLS会话com.ibm.jsse2.clientSessionCacheSize:值设为大于0的整数(例如100),指定客户端会话缓存的最大容量com.ibm.jsse2.clientSessionTimeout:值设为大于0的整数(例如86400,单位秒),指定会话的有效时长
- 保存配置并重启WebSphere实例,原有代码即可正常打印会话信息。
方案2:修改代码获取WebSphere专有SSLContext(无需改全局配置)
直接调用WebSphere提供的SSL工具类获取当前应用实际使用的SSLContext,替换原来获取全局默认SSLContext的逻辑即可:
import com.ibm.websphere.ssl.JSSEHelper; import com.ibm.websphere.ssl.SSLConfig; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSessionContext; import java.io.Writer; import java.security.cert.X509Certificate; import java.util.Enumeration; // 核心逻辑替换 SSLSessionContext sslSessionContext = null; try { SSLConfig sslConfig = JSSEHelper.getInstance().getSSLConfig(null, null, null); SSLContext sslContext = SSLContext.getInstance("TLS", "IBMJSSE2"); sslContext.init(sslConfig.getKeyManagers(), sslConfig.getTrustManagers(), null); sslSessionContext = sslContext.getClientSessionContext(); } catch (Exception e) { // 自行补充异常处理逻辑 } // 后续遍历逻辑和原有代码保持一致 Enumeration<byte[]> sessionIds = sslSessionContext.getIds(); while (sessionIds.hasMoreElements()) { SSLSession sslSession = sslSessionContext.getSession(sessionIds.nextElement()); writer.write("Client: " + sslSession.getPeerHost() + ":" + sslSession.getPeerPort() + "\n"); writer.write("\tProtocol: " + sslSession.getProtocol() + "\n"); writer.write("\tSessionID: " + byteArrayToHex(sslSession.getId()) + "\n"); writer.write("\tCipherSuite: " + sslSession.getCipherSuite() + "\n"); for (X509Certificate certificate : sslSession.getPeerCertificateChain()) { writer.write("\tX509 Certificate: " + certificate.getSubjectDN() + "\n"); writer.write("\t\tIssuer: " + certificate.getIssuerDN().getName() + "\n"); writer.write("\t\tAlgorithm: " + certificate.getSigAlgName() + "\n"); writer.write("\t\tValidity: " + certificate.getNotAfter() + "\n"); } }
额外说明
如果只是要排查WebSphere实例支持的TLS版本,可以直接在管理控制台查看:进入 安全 > SSL证书和密钥管理 > SSL配置 > 选中当前使用的SSL配置(默认是NodeDefaultSSLSettings)> Quality of protection (QoP) settings,页面中的「协议」字段即为当前启用的TLS版本。
内容的提问来源于stack exchange,提问作者João Pedro Schmitt
相关产品推荐
相关产品推荐

