首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何解决SSL握手过程中的“无密码套件”问题?

如何解决SSL握手过程中的“无密码套件”问题?
EN

Stack Overflow用户
提问于 2017-10-07 15:27:56
回答 1查看 9.8K关注 0票数 0

我正在用Tomcat 8 + Java 8构建一个B2B服务,但是我的一个客户不能通过SSL连接到我的服务。在添加SSL调试参数:"-Djavax.net.debug=ssl“后,我看到错误消息:

代码语言:javascript
复制
Is initial handshake: true
Is secure renegotiation: false
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
https-jsse-nio-8445-exec-9, READ: SSLv3 Handshake, length = 62
*** ClientHello, TLSv1
RandomCookie:  GMT: 1490342314 bytes = { 192, 161, 228, 31, 66, 175, 222, 13, 79, 128, 217, 81, 18, 152, 169, 58, 114, 35, 201, 201, 147, 74, 131, 2, 213, 145, 181, 76 }
Session ID:  {}
Cipher Suites: [SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, Unknown 0xff:0x3, SSL_RSA_WITH_RC4_128_MD5]
Compression Methods:  { 0 }
Extension renegotiation_info, renegotiated_connection: <empty>
***
%% Initialized:  [Session-7, SSL_NULL_WITH_NULL_NULL]
https-jsse-nio-8445-exec-9, fatal error: 40: no cipher suites in common
javax.net.ssl.SSLHandshakeException: no cipher suites in common

如何解决错误?

EN

回答 1

Stack Overflow用户

发布于 2017-10-07 15:27:56

以下是我为解决这个问题而分享的经验。

  1. 启用SSL调试参数"-Djavax.net.debug=ssl",发现错误是“没有共同的密码套件”。
  2. 在谷歌了一些页面之后,我安装了“Jurisdiction",http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html,它在JVM级添加了一些密码算法,例如: TLS_RSA_WITH_AES_256_CBC_SHA,但没有解决问题。PS。Ciphers.java是一种有用的代码,可以在JVM级别上显示可用的密码套件。
  3. 在wireshark中捕获网络数据包并进行分析,显示客户端发送ClientHello后,服务器立即断开连接。
  4. 由于我的客户不能用我的测试,我不得不自己重现问题,以加快故障排除过程。然后我找到了代码SslPoke.java并对其进行了修改。它可以通过使用不同的TLS版本或密码套件组合来模拟客户端的请求。我可以自己模拟相同的错误日志,这很有帮助。
  5. 然后,我再次发现,我可以在Tomcat的server.xml中指定密码套件,例如:

<Connector port="${https.port}" SSLEnabled="true" scheme="https" sslProtocol="TLS" ciphers="TLS_RSA_WITH_AES_256_CBC_SHA256... " />

我添加了配置,并通过了SslPoke的测试,情况结束了。

希望这些经验能帮助那些面临同样问题的人。不要忘记检查JVM / Web容器/ App中的密码套件配置。下面的代码也非常有用,感谢提供这些代码的专家。

诚挚的问候,

里昂

代码: Ciphers.java,可从:https://confluence.atlassian.com/bitbucketserverkb/list-ciphers-used-by-jvm-779171661.html找到

代码语言:javascript
复制
public class Ciphers
{
    public static void main(String[] args)
        throws Exception
    {
        SSLServerSocketFactory ssf = (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();

        String[] defaultCiphers = ssf.getDefaultCipherSuites();
        String[] availableCiphers = ssf.getSupportedCipherSuites();

        TreeMap ciphers = new TreeMap();

        for(int i=0; i<availableCiphers.length; ++i )
            ciphers.put(availableCiphers[i], Boolean.FALSE);

        for(int i=0; i<defaultCiphers.length; ++i )
            ciphers.put(defaultCiphers[i], Boolean.TRUE);

        System.out.println("Default\tCipher");
        for(Iterator i = ciphers.entrySet().iterator(); i.hasNext(); ) {
            Map.Entry cipher=(Map.Entry)i.next();

            if(Boolean.TRUE.equals(cipher.getValue()))
                System.out.print('*');
            else
                System.out.print(' ');

            System.out.print('\t');
            System.out.println(cipher.getKey());
        }
    }
}

代码: SslPoke.java,可从:https://gist.github.com/4ndrej/4547029找到

代码语言:javascript
复制
public class SslPoke {

    private static javax.net.ssl.SSLSocketFactory getFactorySimple() throws Exception {
        SSLContext context = SSLContext.getInstance("TLSv1");

        context.init(null, null, null);

        return context.getSocketFactory();

    }

    public static void main(String[] args) {
        System.getProperties().setProperty("javax.net.debug", "ssl");
        System.getProperties().setProperty("https.cipherSuites", "TLS_RSA_WITH_AES_256_CBC_SHA");

        try {
            String urlStr ="https://<your host>:<your port>";
            URL url = new URL(urlStr);

            HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();

            javax.net.ssl.SSLSocketFactory sslSocketFactory = getFactorySimple();

            connection.setSSLSocketFactory(sslSocketFactory);
            InputStream in = connection.getInputStream();

            while (in.available() > 0) {
                System.out.print(in.read());
            }
            System.out.println("Successfully connected");

        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46621924

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档