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

不支持的曲线:Java应用程序上的1.2.840.10045.3.1.7,java,cryptography,wildfly,openjdk,alpine,Java,Cryptography,Wildfly,Openjdk,Alpine,我有一个Java 8应用程序在连接ldaps或https服务器时引发以下异常: Caused by: javax.net.ssl.SSLHandshakeException: Unsupported curve: 1.2.840.10045.3.1.7 我的客户端环境是: Alpine Linux 3.5 on a Docker container OpenJDK 1.8.0_111 Wildfly 10.1.0.Final 如果我从以下位置连接,我可以解决此问题: 使用AES12

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

Caused by: javax.net.ssl.SSLHandshakeException:
    Unsupported curve: 1.2.840.10045.3.1.7
我的客户端环境是:

Alpine Linux 3.5 on a Docker container
OpenJDK 1.8.0_111
Wildfly 10.1.0.Final
如果我从以下位置连接,我可以解决此问题:

  • 使用AES128-SHA密码(TLSv1)的Alpine Linux机箱
  • 使用CentOS 7而不是Alpine Linux 3.5的容器(所有密码都有效)
但如果我从以下位置连接,则始终会失败:

  • 使用ECDHE-RSA-AES256-GCM-SHA384密码(TLSv1.2)的Alpine Linux机箱

有什么建议可以在我的Alpine Linux安装上解决这个问题吗?

TL,DR:Alpine的OpenJDK 8包不支持使用椭圆曲线的密码,如
ECDHE
。在Java选项上使用
-Dcom.sun.net.ssl.enableECC=false
,恳请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());
        }
    }
}
import java.util.Iterator;
导入java.util.Map;
导入java.util.TreeMap;
导入javax.net.ssl.SSLServerSocketFactory;
公共类密码
{
公共静态void main(字符串[]args)
抛出异常
{
SSLServerSocketFactory ssf=(SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
字符串[]defaultCiphers=ssf.getDefaultCipherSuite();
字符串[]availableCiphers=ssf.GetSupportedCipherSuite();
TreeMap密码=新TreeMap();

对于(inti=0;iAlpineLinux3.5的openjdk8 jre基本包8.111.14-r1不包括libsunec.so,SunEC提供程序寻找的库,但是AlpineLinux3.3(8.92.14-r0)和3.4(8.111.14-r0)包含(请参阅)

解决此问题的最简单方法可能是回滚到Alpine 3.4。或者,您可以在3.5中安装openjdk8 jre base的3.4版本,但如果您继续这样做,可能会遇到一些依赖性问题

如果您想使用Alpine Linux 3.5包,可以让java应用程序使用另一个JCE提供程序,如BouncyCastle


如果您不需要EC加密,您可以禁用它,但需要注意的是,这样做会阻止您的应用程序使用几种常见的PFS密码套件。

您知道为什么我们的OpenJDK/IcedTea构建不支持椭圆曲线,以及如何修复它吗?我们并没有故意禁用它。他们可能添加了一个JCA提供程序t确实包括了对ECC的支持,如Bouncy Castle提供商。Oracles提供商是本地的,ECC是一个IP雷区,其中大多数专利已经过时。但这些可能是不包括它的原因。@JakubJirutka请参见下面我的答案,以及相关的阿尔卑斯缺陷。看起来这将很快得到解决。其他信息:曲线:1.2.840.10045.3.1.7也称为“secp256r1”,或NIST也将其称为“P-256”。自Java 7以来,它在Oracle的Java标准运行时环境中可用。