helidon-io / helidon

Java libraries for writing microservices
https://helidon.io
Apache License 2.0
3.52k stars 564 forks source link

ssl localhost error #9530

Open hendrik-weiler opened 10 hours ago

hendrik-weiler commented 10 hours ago

Environment Details


Problem Description

I create a basic project using mvn with this guide https://helidon.io/docs/v4/se/guides/quickstart and i create a jks certificate for using https in localhost.

Here is my resources/application.yaml:

server:
  port: 8080
  host: 0.0.0.0
  tls:
    enabled: true
    keystore:
      path: "keystore.jks"
      passphrase: "changeit"
app:
    greeting: "Hello"

I create the jks with the following command: keytool -genkeypair -alias localhost -keyalg RSA -keysize 2048 -validity 365 -dname "CN=localhost" -keypass changeit -keystore keystore.jks -storepass changeit

I run the application using this command:

#!/bin/zsh
mvn clean package
java -Djavax.net.debug=all -jar target/helidon-quickstart-se.jar

I get the following error in the browser: ERR_SSL_PROTOCOL_ERROR and in the log i get following error:

javax.net.ssl|ALL|13||2024-11-22 13:12:54.122 CET|X509Authentication.java:289|No X.509 cert selected for EC
javax.net.ssl|ALL|13||2024-11-22 13:12:54.122 CET|X509Authentication.java:289|No X.509 cert selected for RSA
javax.net.ssl|WARNING|13||2024-11-22 13:12:54.122 CET|CertificateMessage.java:1057|No available authentication scheme
javax.net.ssl|DEBUG|23||2024-11-22 13:12:54.122 CET|SSLSocketImpl.java:1749|close the underlying socket
javax.net.ssl|DEBUG|23||2024-11-22 13:12:54.122 CET|SSLSocketImpl.java:1775|close the SSL connection (passive)
javax.net.ssl|ERROR|13||2024-11-22 13:12:54.122 CET|TransportContext.java:370|Fatal (HANDSHAKE_FAILURE): No available authentication scheme (
"throwable" : {
  javax.net.ssl.SSLHandshakeException: No available authentication scheme
        at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:130)
        at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:365)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:321)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:312)
        at java.base/sun.security.ssl.CertificateMessage$T13CertificateProducer.onProduceCertificate(CertificateMessage.java:967)
        at java.base/sun.security.ssl.CertificateMessage$T13CertificateProducer.produce(CertificateMessage.java:956)
        at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:437)
        at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.goServerHello(ClientHello.java:1245)
        at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.consume(ClientHello.java:1181)
        at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.onClientHello(ClientHello.java:839)
        at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.consume(ClientHello.java:800)
        at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:393)
        at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:476)
        at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:447)
        at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:201)
        at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172)
        at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1506)
        at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1421)
        at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:455)
        at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:426)
        at io.helidon.webserver.ConnectionHandler.run(ConnectionHandler.java:129)
        at io.helidon.common.task.InterruptableTask.call(InterruptableTask.java:47)
        at io.helidon.webserver.ThreadPerTaskExecutor$ThreadBoundFuture.run(ThreadPerTaskExecutor.java:239)
        at java.base/java.lang.VirtualThread.run(VirtualThread.java:309)}

)
javax.net.ssl|ALL|13||2024-11-22 13:12:54.124 CET|SSLSessionImpl.java:1220|Invalidated session:  Session(1732277574042|SSL_NULL_WITH_NULL_NULL)
javax.net.ssl|ALL|13||2024-11-22 13:12:54.124 CET|SSLSessionImpl.java:1220|Invalidated session:  Session(1732277574115|TLS_AES_128_GCM_SHA256)
javax.net.ssl|DEBUG|13||2024-11-22 13:12:54.126 CET|SSLSocketOutputRecord.java:71|WRITE: TLSv1.3 alert(handshake_failure), length = 2
javax.net.ssl|DEBUG|13||2024-11-22 13:12:54.126 CET|SSLCipher.java:2029|Plaintext before ENCRYPTION (
  0000: 02 28 15 00 00 00 00 00   00 00 00 00 00 00 00 00  .(..............
  0010: 00 00 00                                           ...
)
javax.net.ssl|DEBUG|13||2024-11-22 13:12:54.127 CET|SSLSocketOutputRecord.java:85|Raw write (
  0000: 17 03 03 00 23 B2 E8 34   16 16 E0 44 0A 07 45 D4  ....#..4...D..E.
  0010: 76 1B DD 18 CB 99 0B 98   51 03 F6 E6 97 E5 32 38  v.......Q.....28
  0020: 5B 82 36 FB 1A 5B 33 0F                            [.6..[3.
)
javax.net.ssl|DEBUG|13||2024-11-22 13:12:54.127 CET|SSLSocketImpl.java:1749|close the underlying socket
javax.net.ssl|DEBUG|13||2024-11-22 13:12:54.127 CET|SSLSocketImpl.java:1775|close the SSL connection (passive)
javax.net.ssl|DEBUG|82||2024-11-22 13:14:11.107 CET|SSLSocketInputRecord.java:492|Raw read: EOF
javax.net.ssl|ERROR|82||2024-11-22 13:14:11.109 CET|TransportContext.java:370|Fatal (HANDSHAKE_FAILURE): Couldn't kickstart handshaking (
"throwable" : {
  javax.net.ssl.SSLHandshakeException: Remote host terminated the handshake
        at java.base/sun.security.ssl.SSLSocketImpl.handleEOF(SSLSocketImpl.java:1714)
        at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1514)
        at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1421)
        at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:455)
        at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:426)
        at io.helidon.webserver.ConnectionHandler.run(ConnectionHandler.java:129)
        at io.helidon.common.task.InterruptableTask.call(InterruptableTask.java:47)
        at io.helidon.webserver.ThreadPerTaskExecutor$ThreadBoundFuture.run(ThreadPerTaskExecutor.java:239)
        at java.base/java.lang.VirtualThread.run(VirtualThread.java:309)
  Caused by: java.io.EOFException: SSL peer shut down incorrectly
        at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:494)
        at java.base/sun.security.ssl.SSLSocketInputRecord.readHeader(SSLSocketInputRecord.java:483)
        at java.base/sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:160)
        at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:111)
        at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1506)
        ... 7 more}

)
javax.net.ssl|ALL|82||2024-11-22 13:14:11.110 CET|SSLSessionImpl.java:1220|Invalidated session:  Session(1732277574042|SSL_NULL_WITH_NULL_NULL)
javax.net.ssl|DEBUG|82||2024-11-22 13:14:11.110 CET|SSLSocketOutputRecord.java:71|WRITE: TLSv1.3 alert(handshake_failure), length = 2
javax.net.ssl|DEBUG|82||2024-11-22 13:14:11.110 CET|SSLSocketOutputRecord.java:85|Raw write (
  0000: 15 03 03 00 02 02 28                               ......(
)
javax.net.ssl|DEBUG|82||2024-11-22 13:14:11.111 CET|SSLSocketImpl.java:1749|close the underlying socket
javax.net.ssl|DEBUG|82||2024-11-22 13:14:11.111 CET|SSLSocketImpl.java:1775|close the SSL connection (passive)

Steps to reproduce

  1. Create a basic se project
  2. Generate the certificate for application.yaml in the resources folder
  3. Start the server and visit https://localhost:8080/simple-greet
  4. A ERR_SSL_PROTOCOL_ERROR should appear
romain-grecourt commented 2 hours ago

You have used an alias, you need to configure it:

server:
  port: 8080
  host: 0.0.0.0
  tls:
    enabled: true
    private-key:
      keystore:
        type: "JKS"
        passphrase: "changeit"
        key.alias: "localhost"
        resource:
          path: "keystore.jks"
hendrik-weiler commented 55 minutes ago

Thank you. It works now. This is my new application.yaml:

server:
  port: 8443
  host: 0.0.0.0
  tls:
    enabled: true
    private-key:
      keystore:
        type: "JKS"
        passphrase: "changeit"
        key.alias: "localhost"
        resource:
          path: "src/main/resources/keystore.jks"
      truststore:
        type: "JKS"
        passphrase: "changeit"
        key.alias: "localhost"
        resource:
          path: "src/main/resources/keystore.jks"

The new script for generating the self signed certificate:

#!/bin/zsh
keytool -genkeypair -alias localhost -keyalg RSA -keysize 2048 -validity 365 -dname "CN=localhost" -keypass changeit -keystore keystore.jks -storepass changeit
keytool -export -alias localhost -keystore keystore.jks -rfc -file localhost.cer
keytool -import -alias localhost -file localhost.cer -keystore truststore
keytool -import -file localhost.cer -alias localhost -keystore keystore.jks

I get the following error now: ´´` javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown ´´´

Is it possible to somehow register the certificate that i get no Browser message that the certificate is invalid? I have found something with cacerts and this script https://raw.githubusercontent.com/joshcalafell/SSLKeytool/refs/heads/master/SSLKeyTool.sh when i try to add the certificate to the cacerts file but it needs a password. I have read that it was changeit but that doenst work.