不支持的曲线:Java应用程序中的1.2.840.10045.3.1.7

Joa*_*ais 2 java openjdk cryptography wildfly alpine-linux

我有一个Java 8应用程序在连接ldaps或https服务器时引发以下异常:

Caused by: javax.net.ssl.SSLHandshakeException:
    Unsupported curve: 1.2.840.10045.3.1.7
Run Code Online (Sandbox Code Playgroud)

我的客户环境是:

Alpine Linux 3.5 on a Docker container
OpenJDK 1.8.0_111
Wildfly 10.1.0.Final
Run Code Online (Sandbox Code Playgroud)

如果我从以下位置连接,我可以解决此问题:

  • 使用AES128-SHA密码(TLSv1)的Alpine Linux机器
  • 使用CentOS 7而不是Alpine Linux 3.5的容器(所有密码都可以使用)

但如果我从以下地方连接,将永远失败:

  • 使用ECDHE-RSA-AES256-GCM-SHA384密码的高山Linux机器(TLSv1.2)

是否有建议在我的Alpine Linux安装上解决此问题?

Joa*_*ais 7

TL,DR:来自Alpine的OpenJDK 8软件包不支持使用椭圆曲线的密码ECDHE.使用-Dcom.sun.net.ssl.enableECC=falseJava选项请求OpenJDK不要使用这样的密码.

这篇很好的Atlassian 论文描述了如何使用以下代码从JVM列出所有默认密码和可用密码:

import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import javax.net.ssl.SSLServerSocketFactory;

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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

从Alpine 3.5在OpenJDK 8上运行此代码不会列出任何ECDHE密码,另一方面,相同的代码列出了安装在CentOS 7机箱上的OpenJDK 8的几个这样的密码.

出于某种原因,使用椭圆曲线的密码作为Wildfly应用程序上的可用密码从客户端发送到服务器.在Wildfly之外 - 例如,java SomeClass或者java -jar some.jar这些密码不被发送并且通信起作用.添加-Djavax.net.debug=allJava选项可以观察到此行为.