当前位置: 首页 > 知识库问答 >
问题:

JAVA 6不支持SNI,是否有其他方法通过TLS验证和接受SSL证书?

施海
2023-03-14

我知道浏览器和java7之所以不受影响,是因为它们将服务器名称指示SNI作为SSL信息的一部分发送。因此,apache在启动SSL握手之前知道要使用哪个虚拟主机,并返回正确的证书。Java6不支持SNI。所以我的问题是,如何在Java6中验证并允许证书被接受。

我制作了一个spring客户端来使用webservice,下面是我的代码

public class classname1 {

    static {
        System.setProperty("javax.net.ssl.trustStore", "E://Workspace//keystore");
        System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
        System.setProperty("https.protocols", "SSLv3");
        System.setProperty("https.protocols", "TLSv1");

    }
    static {

                HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()
                    {
                        public boolean verify(String hostname, SSLSession session)
                        {
                            if (hostname.equals("192.168.10.22"))
                                return true;
                            return false;
                        }
                    });
            }

    private static void main(String[] args) {
        try {
            SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
            SOAPConnection soapConnection = soapConnectionFactory.createConnection();

            String url = "https://192.168.10.22/getInformationSearch.asmx?wsdl";
            SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(), url);
            printSOAPResponse(soapResponse);
            soapConnection.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static SOAPMessage createSOAPRequest() throws Exception {
        // ... Code for request, which will be hitted to url
    }

    private static void printSOAPResponse(SOAPMessage soapResponse) throws Exception {
        // ... Code for response, which will fetch information from webservice
        // URL
    }

}

正如您看到的代码,我创建了两个方法,1。对于请求createSOAPRequest()2。对于响应printSOAPResponse()。(Url名称在上述代码段中已更改)

main()方法中,下面的行将生成请求并将该请求发送到给定的url SOAPMessage soapResponse=soapConnection。调用(createSOAPRequest(),url) 之后进入静态块,如上图所示HttpsURLConnection。setDefaultHostnameVerifier()方法。

当时,调试器说:ssl握手失败,ssl对等机错误地关闭。这只发生在Java6中,但这些代码在Java7/8中正常工作。

我尝试了以下java 6中的代码,而不是静态块

 HostnameVerifier hv = new HostnameVerifier() {
                public boolean verify(String urlHostName,
                        SSLSession session) {
                    return true;
                }
            };

但无论如何都不行!!!

我正在使用以下JAR xercesImpl。jar,saajapi。jar,saaj impl。jar,spring-ws-core-1.5.6。jar,spring-ws-security-1.5.6。这个SSL域的jar和证书已经导入密钥库,它在java7/8中工作,所以truststore中没有问题,对吗?(我也使用Java6和java7的keytool制作了2个证书,这两个证书在java7/8中都可以正常工作,但在6中却不行)

我跟着这条线走,但它不起作用。那么,有没有其他方法来验证证书并在java 6环境中获得响应,或者我应该更改任何JAR?


共有2个答案

翟淇
2023-03-14

正如您已经提到的Java6不支持SNI。但是,缺少SNI的问题不仅在于验证证书(因为服务器发送了错误的证书),而且取决于服务器的配置,如果SNI扩展不存在并且不指向主机名,服务器将导致握手错误在服务器上可用。这里显然是这样:

... ssl握手失败,SSL对等端关闭不正确。它只发生在JAVA 6中,但是这些代码在java 7/8中正常工作。

在这种情况下,尝试更改证书的验证将毫无帮助,因为错误甚至在客户端有证书要验证之前就发生了。这意味着没有办法绕过它:如果您想与此特定服务器通信,您需要支持客户端中的SNI。

邓开济
2023-03-14

如果服务器未配置为允许您在没有SNI的情况下进行连接,则无法连接。

如果没有SNI,服务器在建立SSL连接之前无法确定您想要的虚拟主机。

如果您有OpenSSL,您可以使用s_client选项来提取不同的证书,或者在不使用SNI时注意连接失败:

SNI:

echo | openssl s_client -servername www.virtualhost.com -connect 192.168.1.55:443 | openssl x509 -text

用服务器的实际IP地址替换192.168.1.55,并www.virtualhost。com,其中包含要连接到的虚拟主机的主机名。管道前面的echo命令可防止openssl在等待输入时挂起。

没有SNI:

echo | openssl s_client -connect 192.168.1.55:443 | openssl x509 -text

如果没有SNI,您可能会看到一个完全不同的证书,或者您可能会遇到连接错误。

 类似资料:
  • 问题内容: 在golang中,始终将JSON消息中的数字解析为float64。为了检测它是否实际上是整数,我正在检查其类型。不幸的是,没有常数代表。 有没有更优雅的解决方案,而不是使用0或0.0来获取? 问题答案: 您也可以在类型的文档上使用或方法,其可能的值在程序包中作为常量列出。 您也可以在中使用它: 请注意,和都有一个方法,因此,如果您以和开头,都可以使用它。

  • 授权服务器可以支持任何与其安全要求匹配的合适的HTTP身份验证方案。当使用其他身份验证方法时,授权服务器必须定义客户端标识(注册记录)和认证方案之间的映射。

  • 问题内容: 根据Java 7文档以及第三方供应商的说法,似乎Java 7应该支持AES-GCM套件: IBM Java 7 Java 7 SSL文档 在客户端和服务器之间的协商中遇到一些错误,由于仅将其限制为AES- GCM密码而无法协商密码。经过调查,我发现客户端或服务器(tomcat实例)均不支持密码套件。在客户端上运行一些示例代码以获取输出: 不知道是否有人遇到过这样的问题。 Java 7是

  • 我已经在Netty中尝试了双向SSL身份验证 但这个例子不再显示任何信息,只是一个404未找到。我在这里找到了一些帮助: https://github.com/code4craft/netty-learning/blob/master/netty-3.7/src/main/java/org/jboss/netty/example/securechat/SecureChatSslContextFac

  • 问题内容: 我想测试一些在同一类中调用其他方法的方法。它们基本上是相同的方法,但是具有不同数量的参数,因为数据库中有一些默认值。我在这个上展示 因此,我想测试在调用方法getPrice(int)时是否调用了方法getPriceForOne()。基本上像平常一样调用getPrice(int)并模拟getPriceForOne。 请记住,我有一个更为复杂的文件,该文件可供其他人使用,它们必须全部放在一

  • 我正在使用WebSphere Liberty 19.0.0.2和WebProfile-8.0特性,该特性支持JAXRS-2.1和BeanValidation-2.0。为了更好地支持多部分流,我使用Jersey作为JAX-RS实现,而不是Liberty的默认Apache CXF。 有关相关组件版本控制的一些更多上下文信息 Bean验证1.1(JSR 349)、Bean验证2.0(JSR 380) 下