Java、Apache HttpClient、TLSv1.2 和 OpenJDK 7

2024-03-12

我们有一小组运行 OpenJDK v1.7.0_111 的 Tomcat 服务器。我们计划在今年夏天升级并迁移它们,但我们发现与我们交互的客户端 API 在短期内将要求使用 TLSv1.2。我的最终愿望是找到一个配置更改来实现这一点。

那里托管的应用程序以一种非常直接的方式创建它的 SSL 上下文:

SSLContext sslContext = SSLContexts.createDefault()
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);

SSLContexts来自 Apache 的 httpclient 库(版本 4.4.1),并且它如何创建 SSL 上下文也非常简单:

public static SSLContext createDefault() throws SSLInitializationException {
    try {
        SSLContext ex = SSLContext.getInstance("TLS");
        ex.init((KeyManager[])null, (TrustManager[])null, (SecureRandom)null);
        return ex;
    } catch (NoSuchAlgorithmException var1) {
        throw new SSLInitializationException(var1.getMessage(), var1);
    } catch (KeyManagementException var2) {
        throw new SSLInitializationException(var2.getMessage(), var2);
    }
}

并通过挖掘SSLConnectionSocketFactory类,看来它只是使用SSLSocket.getEnabledProtocols()方法来确定哪些协议可供使用。注意this.supportedProtocols在我的例子中为空。

public Socket createLayeredSocket(Socket socket, String target, int port, HttpContext context) throws IOException {
        SSLSocket sslsock = (SSLSocket)this.socketfactory.createSocket(socket, target, port, true);
        if(this.supportedProtocols != null) {
            sslsock.setEnabledProtocols(this.supportedProtocols);
        } else {
            String[] allProtocols = sslsock.getEnabledProtocols();
            ArrayList enabledProtocols = new ArrayList(allProtocols.length);
            String[] arr$ = allProtocols;
            int len$ = allProtocols.length;

            for(int i$ = 0; i$ < len$; ++i$) {
                String protocol = arr$[i$];
                if(!protocol.startsWith("SSL")) {
                    enabledProtocols.add(protocol);
                }
            }

            if(!enabledProtocols.isEmpty()) {
                sslsock.setEnabledProtocols((String[])enabledProtocols.toArray(new String[enabledProtocols.size()]));
            }
        }

我遇到的问题是,在运行一些初步测试时,我无法让这些客户端连接到需要 TLSv1.2 的 API。

在下面的例子中我可以得到URLConnection代码通过包含来完成-Dhttps.protocols=TLSv1.2参数,但我无法连接 Apache 连接。

public static void main(String[] args) throws Exception{
        String testURL = "https://testapi.com";

        SSLContext sslcontext = SSLContext.getInstance("TLS");
        sslcontext.init(null, null, null);

        try {
            SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslcontext);
            CloseableHttpClient client = HttpClients.custom().setSSLSocketFactory(socketFactory).build();

            HttpGet httpget = new HttpGet(testURL);

            CloseableHttpResponse response = client.execute(httpget);
            System.out.println("Response Code (Apache): " + response.getStatusLine().getStatusCode());
        }
        catch (Exception e){
            System.err.println("Apache HTTP Client Failed");
            e.printStackTrace();
        }

        try {
            HttpsURLConnection urlConnection = (HttpsURLConnection) new URL(testURL).openConnection();
            urlConnection.setSSLSocketFactory(sslcontext.getSocketFactory());
            urlConnection.connect();
            System.out.println("Response Code (URLConnection): " + urlConnection.getResponseCode());
        }
        catch (Exception e){
            System.err.println("HttpsURLConnection Failed");
            e.printStackTrace();
        }

    }

随着-Dhttps.protocols=TLSv1.2我已经尝试过-Djdk.tls.client.protocols=TLSv1.2-Ddeployment.security.TLSv1.2=trueJVM参数没有任何运气。

有谁知道如何在此配置中启用 TLSv1.2,而无需升级到 v8 或更改应用程序以专门请求 TLSv1.2 实例?


jdk.tls.client.protocols仅适用于您未使用的 Java 8(大概是 9)。

https.protocols默认情况下仅适用于HttpsURLConnectionhttpclient 不使用哪个。

deployment.*仅适用于您未使用的 JNLP 和小程序(如果任何浏览器仍然允许小程序)。

回答你的问题,至少是 4.5,assuming你用HttpClientBuilder or HttpClients(你没有说),是使用.useSystemProperties() or .createSystem(), 分别;这些do使用相同的系统属性*URLConnection——或者至少其中许多包括https.protocols。您应该检查此集中包含的其他属性是否配置为执行您不想要的操作。这确实需要更改应用程序,但不需要将它们更改为“专门请求......TLSv1.2”。

除此之外,您还可以配置SSLConnectionSocketFactory指定允许的确切协议,如由 @pvg 链接的 Q https://stackoverflow.com/questions/28391798/how-to-set-tls-version-on-apache-httpclient, or SSLContexts.custom().useProtocol(String).build()指定上限——这对于您的情况来说已经足够了,因为向需要 1.2 的服务器提供“最多 1.2”的范围将选择 1.2。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java、Apache HttpClient、TLSv1.2 和 OpenJDK 7 的相关文章

  • 我在socket上设置了超时,发现这个值不能大于21

    我在socket上设置了超时 该值小于21秒才有效 21秒后发现超时还是21秒 public static void main String args SimpleDateFormat sdf new SimpleDateFormat yy
  • MongoTemplate upsert - 从 pojo 进行更新的简单方法(哪个用户已编辑)?

    这是一个简单的 pojo public class Description private String code private String name private String norwegian private String en
  • 手动编辑 Jar 以更改包名称

    我有一个来自外部源的 jar 文件 jar 中的所有类都位于 com xyz 包中 我想将所有类移动到 com xyzold 包中 这是否像解压缩 jar 将 xzy 文件夹重命名为 xyzold 并重新压缩它一样简单 或者我还需要修改每个
  • Java、Oracle 中索引处缺少 IN 或 OUT 参数:: 1 错误

    您好 我使用 Netbeans 8 0 2 和 Oracle 11g Express Edition 在 JSF 2 2 中编写了一个图书馆管理系统 我有几个名为 书籍 借阅者 等的页面 以及数据库中一些名为相同名称的表 我的问题是这样的
  • Spring3/Hibernate3/TestNG:有些测试给出 LazyInitializationException,有些则没有

    前言 我在单元测试中遇到了 LazyInitializationException 的问题 而且我很难理解它 正如你从我的问题中看到的那样Spring 中的数据库会话 https stackoverflow com questions 13
  • 请参阅 Java EE eclipse 调试中的 POST 参数

    我在调试 Java EE 方面没有经验 我更像是一个 javascript 人 我需要查看哪些 HTTP POST 参数到达服务器端 我在表单将其操作指向的 jsp 文件中放置了一个断点 现在我在调试变量窗口中找不到 POST 内容 他们在
  • 正则表达式获取字符串中的第一个数字和其他字符

    我是正则表达式的新手 想知道如何才能只获取字符串中的第一个数字 例如100 2011 10 20 14 28 55 在这种情况下 我希望它返回100 但该数字也可以更短或更长 我在想类似的事情 0 9 但它单独获取每个数字 100 2001
  • 字符串池可以包含两个具有相同值的字符串吗? [复制]

    这个问题在这里已经有答案了 字符串池可以包含两个具有相同值的字符串吗 String str abc String str1 new String abc Will the second statement with new operator
  • Java Microsoft Excel API [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何导入 org.apache.commons.lang3.ArrayUtils;进入 Eclipse [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我如何导入 org apache commons lang3 ArrayUtils 将库添加到 Ecl
  • 我想在java中使用XQuery进行Xml处理

    我想用XQuery用于从 java 中的 Xml 获取数据 但我没有得到需要为此添加哪个 Jar 我在谷歌上搜索了很多 但没有得到任何有用的例子 例如我得到以下链接 https docs oracle com database 121 AD
  • 当您在数组列表上调用remove(object o)时,它如何比较对象?

    当您在 java 中的数组列表上调用remove object o 时 它如何比较对象以找到要删除的正确对象 它使用指针吗 或者它使用 Comparable 接口来比较对象吗 ArrayList remove 依赖于对象的实现Equal方法
  • Java:java.util.ConcurrentModificationException

    我正在制作 2D 目前正在研究用子弹射击 子弹是一个单独的类 所有项目符号都存储在称为项目符号的数组列表中 当它超出屏幕一侧 Exception in thread main java util ConcurrentModification
  • 改变for循环的顺序?

    我遇到一种情况 我需要根据用户输入以不同的顺序循环遍历 xyz 坐标 所以我是 3D 空间中的一个区域 然后是一组像这样的 for 循环 for int x 0 x lt build getWidth x for int y 0 y lt
  • 使用 secp256r1 曲线和 SHA256 算法生成 ECDSA 签名 - BouncyCastle

    我正在尝试使用带有 secp256r1 曲线 P256 的 ECDSA 和用于消息哈希的 SHA256 算法生成签名 我也在使用 Bouncy Castle 库 下面的代码 public class MyTest param args pu
  • 如何初始化静态地图?

    你会如何初始化静态Map在Java中 方法一 静态初始化方法二 实例初始化 匿名子类 或者 还有其他方法吗 各自的优点和缺点是什么 这是说明这两种方法的示例 import java util HashMap import java util
  • Java中的回调接口是什么?

    SetObserver 接口的代码片段取自有效的Java 避免过度同步第67条 public interface SetObserver
  • 使用 JAD 反编译 java - 限制

    我正在尝试使用 Java 中的 JAD 反编译几个 jar 文件 我也尝试过 JD GUI 但运气更差 但出现了很多错误 一种类型 易于修复 似乎是内部类 但我也发现了这段代码 static int SWITCH TABLE atp com
  • 如何解决 PDFBox 没有 unicode 映射错误?

    我有一个现有的 PDF 文件 我想使用 python 脚本将其转换为 Excel 文件 目前正在使用PDFBox 但是存在多个类似以下错误 org apache pdfbox pdmodel font PDType0Font toUnico
  • 摩尔斯电码 至 英语

    我现在的问题是让 摩尔斯电码转英语 正常工作 将英语转换为莫尔斯电码的第一部分工作正常 我知道以前已经有人问过这个问题 但我不知道我做错了什么 我知道我需要在某个地方进行拆分 但我只是不确定将其放在代码中的何处 现在 莫尔斯电码到英语的部分

随机推荐