2

I have a certificate with a generated a CSR within go daddy.

I tried generating my own CSR to get a certificate for my domain. I have followed their tutorial to generate a store with the CSR:

keytool -genkey -alias codesigncert -keypass -keyalg RSA -keysize 2048 -dname "CN=displayname,O=companyname,C=US,ST=state,L=city" -keystore codesignstore -storepass

But the godaddy rejected the generated CSR, so I used the one they generate.

After that I used this command from a tutorial at thomasvitale.com.:

keytool -import -alias <my alias> -file <downloadedcertificate file>.crt -keystore keystore.p12 -storepass password

The generated .p12 keystore wouldn't boot because spring said:

DerInputStream.getLength(): lengthTag=109, too big.

Reading a LOT on that I have found out it was the way the keystore was generated and the version of something. Because of that I had to generate another keystore.

To generate the current problematic keystore I tried following medium.com instructions:

Used this to generate the keystore:

keytool -genkey -alias <alias> -keyalg RSA -keystore <keystore.jks> -keysize 2048

Used this to generate a CSR:

keytool -certreq -alias <alias> -keystore <keystore.jks> -file <domain>.csr

Sent the CSR to generate the ssl certificates, downloading them using the tomcat option. Then imported the certificates:

intermediate certificate: keytool -import -trustcacerts -alias <alias> -file gd_bundle-g2-g1.crt -keystore <keystore.jks>

root certificate: keytool -import -trustcacerts -alias <alias> -file e2e56xxxxf40c7.crt -keystore <keystore.jks>

Then I created the pcks keystore this way:

keytool -importkeystore -srckeystore <keystore.jks> -destkeystore <keystore.p12> -srcstoretype JKS -deststoretype PKCS12 -deststorepass <password> -srcalias <src alias> -destalias <dest alias>

After that, my spring boot config to install the certificate is: After comments on this question I changed to use the JKS and removed ciphers.

server:
    port: 8443
    ssl:
        enabled: true
        key-store-type: JKS
        key-store: classpath:asgard_keystore.jks
        key-store-password: generated
        key-alias: asgard

After installing all those to the p12, the server started okay, but any requests to the server would yield: err_ssl_version_or_cipher_mismatch or SSL_ERROR_NO_CYPHER_OVERLAP

Capturing that in wireshark just said Alert 21 using TLS 1.2 Handshake Failure (40).

I'm using undertow as a server. I don't remember if I used the domain in the name and last name field of the CSR.

Decoding my CSR using digicert tool I got:

Common name
 <my domain>

Organization
 <my org>

Organizational unit
 <my city>

City/locality
 <my city>

State/province
 <my estate>

Country
 <my country>

Signature algorithm
 SHA256

Key algorithm
 RSA

Key size
 2048

Seems I'm doing everything exactly like every single tutorial, and every time something fails :(

As per the comment on the question, the keytool -list calls:

keytool -list for the .jks:

Keystore type: jks                                                                                                                                              
Keystore provider: SUN                                                                                                                                          

Your keystore contains 3 entries                                                                                                                                

Alias name: asgard                                                                                                                                              
Creation date: Dec 7, 2018                                                                                                                                      
Entry type: trustedCertEntry                                                                                                                                    

Owner: CN=Go Daddy Secure Certificate Authority - G2, OU=http://certs.godaddy.com/repository/, O="GoDaddy.com, Inc.", L=Scottsdale, ST=Arizona, C=US            
Issuer: CN=Go Daddy Root Certificate Authority - G2, O="GoDaddy.com, Inc.", L=Scottsdale, ST=Arizona, C=US                                                      
Serial number: 7                                                                                                                                                
Valid from: Tue May 03 07:00:00 UTC 2011 until: Sat May 03 07:00:00 UTC 2031                                                                                    
Certificate fingerprints:                                                                                                                                       
         MD5:  96<removed>:40                                                                                                  
         SHA1: 2<removed>B8                                                                                      
         SHA256: 97:3A<removed>E9:76:FF:6A:62:0B:67:12:E3:38:32:04:1A:A6                                                
Signature algorithm name: SHA256withRSA                                                                                                                         
Subject Public Key Algorithm: 2048-bit RSA key                                                                                                                  
< not relevant >                                                                                                                                                    
]                                                                                                                                                               

*******************************************                                                                                                                     
*******************************************                                                                                                                     

Alias name: intermediate                                                                                                                                        
Creation date: Dec 14, 2018                                                                                                                                     
Entry type: trustedCertEntry                                                                                                                                    

Owner: CN=<removed>, OU=Domain Control Validated                                                                                                        
Issuer: CN=Go Daddy Secure Certificate Authority - G2, OU=http://certs.godaddy.com/repository/, O="GoDaddy.com, Inc.", L=Scottsdale, ST=Arizona, C=US           
Serial number: 5c<removed>                                                                                                                                
Valid from: Fri Dec 07 20:25:19 UTC 2018 until: Mon Dec 07 18:10:35 UTC 2020                                                                                    
Certificate fingerprints:                                                                                                                                       
         MD5:  31<removed>74:77                                                                                                  
         SHA1: 8D:<removed>:C0:F5:AE:0B                                                                                      
         SHA256: 77:14:9<removed>8B:1D:67:46:1A:67:A2:72:2F:2F:9E:F2:16                                                
Signature algorithm name: SHA256withRSA                                                                                                                         
Subject Public Key Algorithm: 2048-bit RSA key                                                                                                                  
< not relevant >                                                                                                                                                               
]                                                                                                                                                               



*******************************************                                                                                                                     
*******************************************                                                                                                                     


Alias name: server                                                                                                                                              
Creation date: Dec 7, 2018                                                                                                                                      
Entry type: PrivateKeyEntry                                                                                                                                     
Certificate chain length: 1                                                                                                                                     
Certificate[1]:                                                                                                                                                 
Owner: CN=<removed>, OU=São Paulo, O=Ideas Farm, L=São Paulo, ST=SP, C=BR                                                                               
Issuer: CN=a<removed>, OU=São Paulo, O=Ideas Farm, L=São Paulo, ST=SP, C=BR                                                                              
< not relevant >                                                                                             
]                                                                                                                                                               
]                                                                                                                                                               

*******************************************                                                                                                                     
*******************************************                                                                                                               

full report: pastebin report

I have removed parts of the response that I find not relevant. I found it weird that the pkcs (.p12) file reported as being a jks type.

Also, the files that I received form the certificate authority are:

5<removedhex>6b1b.crt
gd_bundle-g2-g1.crt
gdig2.crt.pem

The gd_bundle contains 3 certificates -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- three times. The other two are just one.

  • You have probably created a keystore with no key, although it could depend on what clients you are using, which you didn't say. You have suppressed enough information (and misformatted more) I can't guess what you actually did, but one thing jumps out: the filename you identify as 'root certificate' is not plausibly a root and almost certainly the server cert. If that isn't the (only) problem, look at the keystores with `keytool -list` (and perhaps `-v`) to see what is actually in each one and compare to what should be. And it may matter what Java version you are using, which you didn't say. – dave_thompson_085 Dec 14 '18 at 00:04
  • I have edited my question with all relevant keystore -list commands and some more observations. – Lucas Montenegro Carvalhaes Dec 14 '18 at 12:58
  • Re p12 vs jks: in Java 8 update 60 and up the "JKS" keystore provider can actually read PKCS12 as well; see [the release notes](https://www.oracle.com/technetwork/java/javase/8u60-relnotes-2620227.html). This was a transition step to java 9 and up which use PKCS12 (and not JKS) by default. – dave_thompson_085 Dec 14 '18 at 20:39

2 Answers2

1

You have told java to use the certificate with an alias of asgard. I can see in your .p12 dump that "asgard" is actually a CA. Look at the owner:

Alias name: asgard
Creation date: Dec 14, 2018
Entry type: trustedCertEntry

Owner: CN=Go Daddy Secure Certificate Authority - G2, OU=http://certs.godaddy.com/repository/, O="GoDaddy.com, Inc.", L=Scottsdale, ST=Arizona, C=US
Issuer: CN=Go Daddy Root Certificate Authority - G2, O="GoDaddy.com, Inc.", L=Scottsdale, ST=Arizona, C=US

I'm guessing that you actually want to tell spring to load your .jks file and specify an alias of codesigncert.

Also, delete your ciphers and enabled-protocols properties unless you have a good reason to override what spring sets up as defaults. Spring keep their defaults up to date with the latest security bulletins.

Finally, change your keystore password because the whole internet now knows what it is :)

Andy Brown
  • 11,766
  • 2
  • 42
  • 61
  • I'll try all that. The keystore pw is just a test, we actually use vault to store sensible data. :) So, just to be clear, I have to use the jks directly and not the pkcs (p12) file? – Lucas Montenegro Carvalhaes Dec 14 '18 at 15:57
  • 1
    Both PKCS12 and JKS formats are supported by Spring. You should add "codesigncert" as your "PrivateKeyEntry" and configure Spring to use it. You should import your issuer CA and any intermediates as "trustedCertEntry" entries so that SSL calls that reach you will be able to validate issuers up the chain to the root. – Andy Brown Dec 14 '18 at 16:19
  • How do I import those to the jks? – Lucas Montenegro Carvalhaes Dec 14 '18 at 18:33
  • Actually I just realised also that the first list command I did was keytool -list without any -keystore parameter... – Lucas Montenegro Carvalhaes Dec 14 '18 at 18:40
  • Changing to the jks and to the codesigncert I have managed to get a NET::ERR_CERT_AUTHORITY_INVALID. I think it is because the jks is missing the intermediate trustedCertEntries. – Lucas Montenegro Carvalhaes Dec 14 '18 at 19:33
  • Not missing those appearently. I have added one certificate that was missing in the jks and updated the question with the full keytool list report. Still stuck at the NET::ERR_CERT_AUTHORITY_INVALID – Lucas Montenegro Carvalhaes Dec 14 '18 at 20:21
  • 1
    I agree `asgard` is wrong, but I don't see any `codesigncert` in the dumps posted. @Lucas: the entry named `server` is the only private key entry in your list, and from the timing does appear to be your actual privatekey but with your dummy/selfsigned cert which will cause cert_authority_invalid in Chrome (varies in other). You need to import the server cert issued by the CA (which should be (hex).crt) **to alias `server`** (in the keystore used). (As Andy said you also should have the intermediate cert(s) already in the keystore, which you do, though under a misleading name.) – dave_thompson_085 Dec 14 '18 at 20:58
  • 1
    Set the Spring `server.ssl.trust-store.*` properties to the equivalent values that you have for your keystore. Run your java server with `-Djavax.net.debug=all`. It will be noisy. Watch first for the log output that dumps your truststore. You want it to be showing your truststore and not the default JDK one (the one that contains dozens of internet CAs). Then watch the output immediately when your client connects. You will see the progress of the handshake and where it gives up. – Andy Brown Dec 15 '18 at 07:54
  • I have done that. Added the trust-store properties and runned with the debug setting to all. The first thing that appears is "Ignoring unsupported cipher suite" for every cipher suite. `Using SSLEngineImpl.` `Allow unsafe renegotiation: false` `Allow legacy hello messages: true` `Is initial handshake: true` `Is secure renegotiation: false` Then it says Unsupported extension many times for random data excerpts. – Lucas Montenegro Carvalhaes Dec 17 '18 at 13:34
  • Are you by any chance running the server with a JRE that does not have the JCE unlimited strength crypto policy files installed? – Andy Brown Dec 17 '18 at 13:39
  • Are there mandatory alias names that I should be following? None of the online docs I've read talk about that... is `codesigncert` an alias name that I have to use? Also, when I added the hex.crt certificate it added 2 certificates to the keystore. One that appears to be the CA and another that appears to be my server certificate. The one I found that would be the server cert is this: Alias name: server Entry type: trustedCertEntry Owner: CN=asgard.ideas.farm, OU=Domain Control Validated Issuer: CN=Go Daddy Secure Certificate Authority ... – Lucas Montenegro Carvalhaes Dec 17 '18 at 13:40
  • I'm running oracle JRE 9 everything default. – Lucas Montenegro Carvalhaes Dec 17 '18 at 13:41
  • I can't get a privateKeyEntry that is not that dummy certificate where the issuer is myself. I have tried adding every certificate from the issuer... – Lucas Montenegro Carvalhaes Dec 17 '18 at 13:56
  • There is no mandatory alias naming scheme. The only rule is that the `privateKeyEntry` (your combined private key/certificate) alias name matches the name given to spring in the keystore properties. The other alias names (all the `trustedCertEntry` CAs) are irrelevant and have no use in practice. The cert path checking algo finds them all and uses them to try to resolve the path back from the cert presented by the caller to a trusted root (a self-signed CA). – Andy Brown Dec 18 '18 at 08:40
  • That stuff about ignoring all cipher suites is worrying. Can you check the procedure given in this [accepted answer](https://stackoverflow.com/a/30760134/1763035) and double-check that you really are launching your server with the JVM version that you think you are (e.g. multiple JRE's installed on your system). – Andy Brown Dec 18 '18 at 08:44
1

I have solved the problem.

After fiddling A LOT with each certificate, I have found out that GoDaddy issues the certificate response and 2 equal intermediate certificates. Both come in the download package and there is no root certificate in there.

What happened is that I had a self signed dummy key, as stated in the comments and I didn't knew that I had to import the server certificate (the certificate response) with the same alias as my private key. I was importing with another alias thinking it was something else. My private key would remain self signed and not validated.

The errors I was getting about ciphers were because I was telling spring to use a certificate that was not a private key. Those don't support decoding the handshake.

Another problem that I faced is that godaddy doesn't provide the root certificate in the bundle you download. I was trying to add two intermediates, while the root was avaliable at a repository they had. After downloading and importing the correct root certificate, then I was able to import the private key validation certificate to the same alias as my dummy key.

So the solutin was simply to start with the JKS keystore used to create the CSR (one that contains only the private key I generated). Then add to it the root and intermediate certificates, and finally add the server cert (the one with the hex name), with the same alias as the private key.

  • may I know where your spring boot app is hosted? I am currently hosting my spring boot app in azure cloud which is accessed via the IP address. I learnt that its not possible to secure an application if its accessed via ip address. – user1456110 Jul 30 '20 at 12:42
  • It was hosted on digital ocean. – Lucas Montenegro Carvalhaes Jul 30 '20 at 14:09
  • Thanks. in my case i am running it as jar executable in a linux vm in azure. I am accessing those spring boot api endpoints via its ip address. in that case, do you know what should be the domain name in the SSL certificate? – user1456110 Jul 30 '20 at 16:04
  • I don't think the host/machine makes a difference on how spring loads its certificate chain. The only thing that would change it would be if you are using a different server to run java. I was running with spring boot and undertow. I believe undertow, jboss, glassfish would all run the same and tomcat with your software as a war could load the certificate in another way. Embedded tomcat though would probably behave exactly like jboss. – Lucas Montenegro Carvalhaes Aug 01 '20 at 05:39