java.lang.Exception: Public keys in reply and keystore don't match

97,370

Solution 1

The link in your question explains how to create an SSL keystore for a server, which is not what you want to do. What you did was:

  1. Create a new key pair
  2. Add a trusted certificate to the keystore
  3. Add another trusted certificate to the keystore
  4. Try to import the SSL certificate of the server as a certificate for your key pair

Step 4 fails because the SSL certificate was generated for a completely different key pair.

The three certificates are probably:

  1. The SSL certificate of the webservice
  2. The CA certificate that signed the SSL certificate
  3. The root certificate that signed the CA

What you have to do now is to add a trust anchor to your truststore (by default: ${JAVA_HOME}/jre/lib/security/cacerts), with the result that your client accepts the SSL certificate of the webservice.

Usually the SSL server sends the whole chain except for the root certificate to the client during SSL handshake. This means that you have to add the root certificate to your truststore:

keytool -import -keystore ${JAVA_HOME}/jre/lib/security/cacerts -file CCA_Certificate.cer -alias theCCARoot

Additional steps are necessary if the webservice requires SSL client authentication, but you have never mentioned client authentication, so I assume that it is not necessary.

Solution 2

The issue here is the alias you used while importing the certificate which is similar to the one you used while creating the JKS store. Just change the alias and it will solve your issue. The source document [1] needs to be corrected accordingly.

[1] http://docs.oracle.com/cd/E19509-01/820-3503/ggfgo/index.html

Solution 3

In the 4 point (where you are getting error : keytool error: java.lang.Exception: Public keys in reply and keystore don't match) where you are importing the certificate, please change the alias. The alias should not be npci_client_testore as it is already used for alias of keystore.

Solution 4

In my case the "The root certificate that signed the CA" was missing from the chain. Please check if you have the appropriate ROOT CA certificate otherwise export it from the Intermediate and import it in the keystore. Importing the Root CA into my keystore worked for me.

Solution 5

I had the same exception error (keystore don't match) hosting with Tomcat8. If you have entered a wrong domain name or no domain name while creating your keystore, you will need to re-create your Keystore file again and resubmit your CSR again to your Certification Authority (CA) licensed/recognised/approved to issue Digital Signature Certificates (Godaddy in my case).

Here are the commands to create a keystore file:

keytool -keysize 2048 -genkey -alias tomcat -keyalg RSA -keystore tomcat.keystore
keytool -importkeystore -srckeystore tomcat.keystore -destkeystore tomcat.keystore -deststoretype pkcs12

(You need to enter the domain name when the prompt asks for a first and last name, it is requesting the Fully Qualified Domain Name (FDQN) e.g. www.example.com). From the City, State and Province - do not abbreviate

Enter the following command to create the CSR (from the same directory as your tomcat.keystore location):

keytool -certreq -keyalg RSA -alias tomcat -file myFQDN.csr -keystore tomcat.keystore

Note: Because of the previous "keystore don't match" error, I had to delete all my Godaddy certificates from my windows console (MMC).

Once your Certificate files are ready from your Certification Authority. Download the files and double click on each of the 2 .crt files to reinstall them again in windows (Choose automatically install in Local Machine). Make sure you backup your tomcat.keystore file then import these certificate files IN ORDER into your tomcat.keystore file (from scratch) with the same order as the following example:

keytool -import -alias root -keystore tomcat.keystore -trustcacerts -file gdig2.crt.pem
keytool -import -alias intermed -keystore tomcat.keystore -trustcacerts -file gd_bundle-g2-g1.crt
keytool -import -alias tomcat -keystore tomcat.keystore -trustcacerts -file namewithnumbersandletters.crt

Make sure you have updated your server.xml then restart your Tomcat

<Connector port="80" protocol="HTTP/1.1"
    relaxedQueryChars="|{}[]%-"
    connectionTimeout="20000"
    redirectPort="443" />  
<Connector  SSLEnabled="true" URIEncoding="UTF-8" 
    clientAuth="false" 
    keystoreFile="C:\Program Files\Java\jdk-11.0.9\bin\tomcat.keystore" 
    keystorePass="ChangeToYourPassword" 
    maxThreads="200" 
    port="443" 
    scheme="https" 
    secure="true" 
    sslProtocol="TLS"
    sslEnabledProtocols="TLSv1.2"
    ciphers="TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
    TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
    TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
    TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" /> 

Voilà! The Locked icon (Secure Connection) appears when browsing on the domain.

Share:
97,370
dReAmEr
Author by

dReAmEr

Open source enthusiatic

Updated on May 18, 2021

Comments

  • dReAmEr
    dReAmEr almost 3 years

    I have to access a webservice hosted at port 443.Service provider has shared three certificate with us.

    1. ABCD.cer
    2. CA_Certificate.cer
    3. CCA_Certificate.cer

    I have to add them to keystore by creating a form chain for the SSL communication.I have followed below steps.

    1. keytool -keystore npci_keystore_test.jks -genkey -alias npci_client_testore

         Result :- keystore npci_keystore_test.jks created.
      
    2. keytool -import -keystore npci_keystore_test.jks -file CA_Certificate.cer -alias theCARoot

         Result :- certificate CA_Certificate.cer is added to keystore.
      
    3. keytool -import -keystore npci_keystore_test.jks -file CCA_Certificate.cer -alias theCCARoot

         Result :- certificate CCA_Certificate.cer is added to keystore.
      
    4. keytool -import -keystore npci_keystore_test.jks -file ABCD.cer -alias npci_client_testore

      At the step 4 i have below exception

      Enter keystore password: (and when i enter password i have below exception)

      keytool error: java.lang.Exception: Public keys in reply and keystore don't match

    I have already done search in SO,but so far no luck.

    I am following below source to create the store and import certificate in it. JKS Keystore

    EDIT:---

    I have tested it by changing the import order of certificate,but no luck so far.

  • dReAmEr
    dReAmEr over 9 years
    Do you mean first i will have to add Root certificate CCA (in my case) in truststore and rest (ABCD,CA) in keystore??
  • Omikron
    Omikron over 9 years
    No, as long as you do not need client authentication, no keystore is required at all.
  • dReAmEr
    dReAmEr over 9 years
    I actually need to make call from JAVA client to a rest service(Third party) hosted at port 443, does it mean that i need to import all these certificate to trust store only?
  • Omikron
    Omikron over 9 years
    You can use KeyStore Explorer to check if client authentication is required: Tools -> Examine SSL (leave "Enable Client Authentication" unchecked). If you can access the service without errors, then is is not required.
  • Michael Biniashvili
    Michael Biniashvili over 7 years
    but in this case there will be no chaninig between the key and the certificate
  • Pinkie Swirl
    Pinkie Swirl over 5 years
    Before you post an answer to an already answered question please make sure you add something new. Then explain why your suggestion worked for you (thats what stackoverflow is for).
  • scopchanov
    scopchanov about 5 years
    How is this different than the solution proposed by @RavindraRanwala on Jul 1 '16 at 3:19?
  • GvSharma
    GvSharma over 2 years
    what is this? this doesn't add anything new or extra to existing