SSL握手异常:没有可用的身份验证方案。

9
通过谷歌搜索发现在jdk11.0.2版本中存在一个bug,但是我已经升级到jdk11.0.3版本,但问题仍然存在。重现步骤如下:
  1. git clone https://github.com/deanhiller/webpieces.git
  2. "org.gradle.java.home=/Library/Java/JavaVirtualMachines/jdk-11.0.3.jdk/Contents/Home" 添加到 ~/.gradle/gradle.properties 以设置jdk版本为11.0.3
  3. 从webpieces目录运行命令 ./gradlew :core:core-asyncserver:test
测试用例会被挂起,在日志中显示:
Caused by: javax.net.ssl.SSLHandshakeException: No available authentication scheme
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:128)
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:308)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:255)
    at java.base/sun.security.ssl.CertificateMessage$T13CertificateProducer.onProduceCertificate(CertificateMessage.java:945)
    at java.base/sun.security.ssl.CertificateMessage$T13CertificateProducer.produce(CertificateMessage.java:934)
    at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436)
    at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.goServerHello(ClientHello.java:1224)
    at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.consume(ClientHello.java:1160)
    at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.onClientHello(ClientHello.java:849)
    at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.consume(ClientHello.java:810)
    at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
    at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444)
    at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1065)
    at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1052)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:999)
    at org.webpieces.ssl.impl.AsyncSSLEngine2Impl.createRunnable(AsyncSSLEngine2Impl.java:94)
    ... 12 common frames omitted

我应该提交另一个JDK bug吗,还是有人有想法?

已解决/相关的JDK bug:https://bugs.openjdk.java.net/browse/JDK-8211426

请注意,以下代码可以解决它: System.setProperty("jdk.tls.server.protocols", "TLSv1.2");

嗯,有人知道如何生成适用于TLSv1.2和TLSv1.3的自签名证书吗?


3
您提供的相关错误链接显示其解决方案为“不修复”,因此尚未修复。有一篇评论指出了解决此问题的方法,即不使用TLS1.3而是“降级”到TLS1.2。请检查是否解决了您的问题。 - Misantorp
是的,我想我必须弄清楚如何将证书升级到TLS 1.3,但是仍然可以在JDK 8、9、10等中使用TLS 1.2。希望新证书可以在JDK 8到JDK 12的所有5个版本中工作。 - Dean Hiller
1
“...生成一个适用于TLSv1.2和TLSv1.3的自签名证书…” - 证书大多数情况下与TLS协议版本无关。除了DSA证书将无法与TLS 1.3一起使用 - 但今天谁还在使用DSA呢。请在证书内使用ECC密钥或RSA密钥。因此,问题更多地是您首先如何创建这个自签名证书以及它的外观如何。 - Steffen Ullrich
1个回答

8
假设问题与TLS 1.3无关,而是与证书本身有关。
您的证书使用了已经被淘汰的DSA算法,建议改用更为安全的RSA算法,因为在TLS1.3中不再支持DSA。请确保创建RSA证书。
似乎不太久之前的Java keytool版本默认使用DSA证书,这是一个不幸的设置。您可以使用以下命令验证证书的类型:
openssl x509 -in certificate.crt -text
Certificate:
    ...
    Signature Algorithm: dsa_with_SHA256
        ...
        Subject Public Key Info:
            Public Key Algorithm: dsaEncryption

在使用Java时,keytool -printcert -file $filekeytool -list -keystore $ksfile [-alias $name] -v也会显示此信息。(前者适用于PEM和DER文件而无需更改,而openssl需要-inform der或缩写-inform d。) - dave_thompson_085
1
SHA-1签名算法在Java的TLSv1.3中也不可用。在https://tools.ietf.org/html/rfc8446#section-4.4.2.4中解释:“SHA-1已被弃用,建议任何接收到使用SHA-1哈希的签名算法验证证书的终端中止握手并发出“bad_certificate”警报。” - Lari Hotari
降级到TLSv1.2在我的情况下也没有帮助,它显示空的客户端证书列表,尽管证书存在于KeyStore中。有什么帮助吗? - Pankaj Goyal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接