首页 > 解决方案 > 如何使用 IBMJSSE2 默认提供程序从 SSLContext 获取所有 TLS 会话?

问题描述

我使用为 TLS 连接提供的默认值,IBMJSSEProvider2并且我有以下代码来显示有关 TLS 会话的信息:

SSLSessionContext sslSessionContext = SSLContext.getDefault().getClientSessionContext();
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 8.5 的一个实例上运行。当我运行这个算法时,它不会打印关于我使用RestTemplateSpring 3.2 的实现与任何 HTTPS URL 建立的连接的任何信息。使用来自 Oracle 的其他提供程序会显示信息。我是否缺少使它起作用的东西?

我正在尝试制作一个简单的解决方案来解决 WebSphere 的实时实例支持哪些 TLS 版本。当然,不建议现场客户使用此方法。

标签: javasecuritysslwebspheretls1.2

解决方案


问题在于,底层库可能没有使用 WebSphere 上的默认上下文。因此,我必须创建一个自定义客户端来使用特定的 SSLContext,这样我就可以列出我需要的所有信息。以下是实现此目的的代码:

    private static String URL = "https://www.google.com";
    private static String TRUST_STORE_FILE = "/Users/xpto/trust.p12";
    private static String TRUST_STORE_PASS = "truststore";
    private static String TRUST_STORE_TYPE = "PKCS12";
    private static String TLS_VERSION = "TLSv1.2";

    public static void main(String[] args) throws Exception {
        KeyStore keyStore = KeyStore.getInstance(TRUST_STORE_TYPE);
        keyStore.load(new FileInputStream(TRUST_STORE_FILE), TRUST_STORE_PASS.toCharArray());

        SSLContext sslContext = SSLContexts
                .custom()
                .loadTrustMaterial(keyStore)
                .useProtocol(TLS_VERSION)
                .build();

        HttpComponentsClientHttpRequestFactory clientFactory = new HttpComponentsClientHttpRequestFactory(HttpClients
                .custom()
                .setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext))
                .build());

        RestTemplate restTemplate = new RestTemplate(clientFactory);

        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.setContentType(MediaType.APPLICATION_JSON);
        requestHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));

        HttpEntity<String> requestEntity = new HttpEntity<String>(requestHeaders);
        print("Requesting: " + URL);
        ResponseEntity<String> response = restTemplate.exchange(URL, HttpMethod.GET, requestEntity, String.class);
        print("Response: " + response.getBody());

        printSSLContextInfo(sslContext);
    }

    private static void printSSLContextInfo(SSLContext sslContext) throws Exception {
        print("-------------\nPrinting TLS Client Information");
        SSLSessionContext sslSessionContext = sslContext.getClientSessionContext();
        Enumeration<byte[]> sessionIds = sslSessionContext.getIds();
        while (sessionIds.hasMoreElements()) {
            SSLSession sslSession = sslSessionContext.getSession(sessionIds.nextElement());
            print("Client: " + sslSession.getPeerHost() + ":" + sslSession.getPeerPort());
            print("\tProtocol: " + sslSession.getProtocol());
            print("\tSessionID: " + byteArrayToHex(sslSession.getId()));
            print("\tCipherSuite: " + sslSession.getCipherSuite());
            for (X509Certificate certificate : sslSession.getPeerCertificateChain()) {
                print("\tX509 Certificate: " + certificate.getSubjectDN());
                print("\t\tIssuer: " + certificate.getIssuerDN().getName());
                print("\t\tAlgorithm: " + certificate.getSigAlgName());
                print("\t\tValidity: " + certificate.getNotAfter());
            }
        }
    }

    public static String byteArrayToHex(byte[] a) {
        StringBuilder sb = new StringBuilder(a.length * 2);
        for (byte b : a)
            sb.append(String.format("%02x", b));
        return sb.toString();
    }

    public static void print(Object msg) {
        System.out.println(msg);
    }

推荐阅读