Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ssl localhost error #9530

Closed
hendrik-weiler opened this issue Nov 22, 2024 · 7 comments
Closed

ssl localhost error #9530

hendrik-weiler opened this issue Nov 22, 2024 · 7 comments

Comments

@hendrik-weiler
Copy link

hendrik-weiler commented Nov 22, 2024

Environment Details

  • Helidon Version: 4.1.4
  • Helidon SE
  • JDK version: openjdk 21.0.1
  • OS: MacOS
  • Docker version (if applicable):

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
Copy link
Contributor

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
Copy link
Author

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.

@romain-grecourt
Copy link
Contributor

IIRC with Firefox you can directly register certificates, with other browsers you need to add them to your OS (keychain on macOS, mmc on Windows etc.)

Not sure where your java exception is coming from, are you using a Java HTTP client ?
You need to import your certificate in $JAVA_HOME/lib/security/cacerts.

If you are using Helidon WebClient you can configure TLS with a truststore:

client:
  tls:
      truststore:
        type: "JKS"
        passphrase: "changeit"
        key.alias: "localhost"
        resource:
          path: "src/main/resources/keystore.jks"

@hendrik-weiler
Copy link
Author

Ok i tried to add it in osx 15.1 into the key chain.
This is my code:

#!/bin/zsh
keytool -genkeypair -alias localhost -keyalg RSA -keysize 2048 -validity 365 -dname "CN=localhost" -keypass changeit -keystore keystore.jks -storepass changeit
keytool -v -certreq -keystore keystore.jks -alias localhost -file cert-file.cer
keytool -certreq -keystore keystore.jks -storepass changeit -alias localhost -file cert-file.csr
keytool -gencert -keystore keystore.jks -storepass changeit -alias localhost -infile cert-file.csr -outfile cert-file.cer

I created a cer file and reigistered it in the keychain. Also trusted that certificate.
But i still get the net::ERR_CERT_INVALID error in the chrome browser.
I am only using the application as server and want to get a self signed certificate that is trusted like a paid certificate or from letsencrypt.
I have seen that c# blazor webassembly creates certificates to enable to develop with https even as self signed.

The exception comes from when i start the heldion server like that:

java -Djavax.net.debug=all -jar target/helidon-quickstart-se.jar

@romain-grecourt
Copy link
Contributor

I think the first keytool command should be enough to generate a self signed certificate.
Are you seeing a Java exception ?

@hendrik-weiler
Copy link
Author

I found the answer to how to create a valid self signed certificate.
Heres the code that works:

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

It will generate the jks file and the .cer certificate for the keychain. In the keychain you have to trust the certificate.

@romain-grecourt
Copy link
Contributor

JKS is a proprietary format only used by Java, it is actually not recommended to use.

In most cases you are better off using PEM or PKCS12, as well as openssl instead of keytool.
Helidon supports all three types (JKS, PEM, PKCS12).

Also it seems that macOS Keychain Access only supports PKCS#12.

Closing this issue as it seems resolved.

@github-project-automation github-project-automation bot moved this from Triage to Closed in Backlog Nov 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

No branches or pull requests

2 participants