Hi,

for development reasons, I implemented a Gradle Task, that generates new certificates from a given intermediate certificate (root & intermediate certificate are made via OpenSSL). This task generates both: PEM files & Key-/Trust Stores, because we have different applications that work together. Some can't handle PEM, others can't handle PKCS#12. Therefore, I need both.

The problem:

My web browser (FireFox) gets an invalid signature algorithm (which should be the usual: SHA256 with ECDSA):

pem

But if I take the Key-/Trust stores everything works as expected

store

I inspected the certificate file with Windows Certificate Manager-Tool (certlm.msc) and there seems nothing extraordinary...

windows


Certificates zipped: certs.zip

Passwords for Key stores & encrypted Private Key (although there is also an unencrypted one...) can be found password.property file.

Specs

  • Spring Boot: v.3.1.3
  • Spring Dependency Management: v.1.1.3
  • Gradle: v.8.1.1
  • OS: Windows 10

Properties excerpt for SSL

server.ssl.enabled = true
# Client authorization choices: none, want, need
server.ssl.client-auth = none
# Tell webserver to use a specific SSL bundle
#server.ssl.bundle = web-server

# ----- PKCS#12 -------
## Key store
#server.ssl.key-store = classpath:certs/webserverTestKeyStore.p12
#server.ssl.key-store-type = PKCS12
#server.ssl.key-alias = webserver
#server.ssl.key-store-password = superSECRETwebserver
## Trust store
#server.ssl.trust-store = classpath:certs/webserverTestTrustStore.p12
#server.ssl.trust-store-type = PKCS12

# ----- PEM -------
# Key store
server.ssl.certificate = classpath:certs/webserverTest.crt
server.ssl.certificate-private-key = classpath:certs/webserverTestUnprotected.key
# Trust store
server.ssl.trust-certificate = classpath:certs/testCA.crt

# ----- SSL Bundles - PKCS#12/JKS -------
# Key store
#spring.ssl.bundle.jks.web-server.keystore.location = classpath:certs/webserverTestKeyStore.p12
#spring.ssl.bundle.jks.web-server.keystore.provider = BC
#spring.ssl.bundle.jks.web-server.keystore.type = PKCS12
#spring.ssl.bundle.jks.web-server.key.alias = webserver
#spring.ssl.bundle.jks.web-server.keystore.password = superSECRETwebserver
# Trust store
#spring.ssl.bundle.jks.web-server.truststore.location = classpath:certs/webserverTestTrustStore.p12
#spring.ssl.bundle.jks.web-server.truststore.provider = BC
#spring.ssl.bundle.jks.web-server.truststore.type = PKCS12

# ----- SSL Bundles - PEM -------
# Key store
#spring.ssl.bundle.pem.web-server.keystore.certificate = classpath:certs/webserverTest.crt
#spring.ssl.bundle.pem.web-server.keystore.private-key = classpath:certs/webserverTestUnprotected.key
# Trust store
#spring.ssl.bundle.pem.web-server.truststore.certificate=classpath:certs/testCA.crt

Update

OK..., this seems to be a specific FireFox problem.

But then again, why is it working with Key-/Trust Stores but not with PEM files?!?

Chrome

chrome

Edge

edge

Comment From: mhalbritter

I think you hit this issue: https://github.com/spring-projects/spring-boot/issues/34232#issuecomment-1699454963

Your key seems to be in the "PKCS#1" (it's SEC 1 because there's no PKCS#1 for EC keys) format.

Can you try this key and see if it works (this is your key converted to PKCS#8)?

webserverTestUnprotected.key.zip

I used openssl pkcs8 -topk8 -in private-key-ec.pem -nocrypt -out private-key.pem to convert your key.

How did you create this key?

Comment From: aDramaQueen

Will check this without the EC part. Give me some minutes...

I used Bouncy Castle v.1.7.3. This is the code to create the unprotected private key:

public static void writeToPEMFile(Object object, File targetFile, boolean appendToFile) throws IOException {
        FileWriter fileWriter = new FileWriter(targetFile, appendToFile);
        JcaPEMWriter pemWriter = new JcaPEMWriter(fileWriter);
        pemWriter.writeObject(object);
        pemWriter.close();
        fileWriter.close();
}

Object may be one of following classes: - X509Certificate - X509CRL - KeyPair - PrivateKey - PublicKey

Comment From: mhalbritter

Our "PKCS#1 for EC" parser has some serious limitations (it only supports one curve, and this is the secp384r1 curve). All other curves may or may not be parsed, and this will lead to the SSL handshake failing in strange ways, see https://github.com/spring-projects/spring-boot/issues/34232 for details.

You should create PKCS#8 keys in PEM format (the things which start with -----BEGIN PRIVATE KEY-----) - these work.

Comment From: aDramaQueen

OK, your converted PEM key works.

But then again, why is it just FireFox and not Chrome/Edge?!? Hmm..., anyways. I guess I have to adapt the code from above.

Thanks.

Comment From: philwebb

@aDramaQueen You might want to try the latest SNAPSHOT since a fix for #34232 has recently been pushed.