-1

I am working on a application which is required to consume a Rest API which uses SSL mutual handshake. The Rest service provider has shared a certificate which even they are not sure is the correct one or not and further looking into this. I have looked into the web regarding SSL configuration and communication, however, practically I still have doubts.

I have read client should be using using the server certificate (public key) and their own private key to make requests. If my understanding is right following are my questions

  1. How do I make my private key for this purpose? I tried using keytool to generate keystore, which by default creates a private key I think. Is this the right way?

  2. Am I supposed to get a server certificate/public key?

  3. If the answer to the above question is yes, then should I import that certificate to my keystore which I created and then use the keystore for communication?

Edit: I just want to put a little more details here. The application I am working in (Client) is already in production and also uses SSL. So, can I get the get the public key/certificate of my application by hitting the application the browser? I have found that the CA for my application as well the application hosting the rest api is same. I am just thinking if I really need to create a key pair and get it signed by a CA in my case or leverage any existing one?

  • 1
    *"I have read client should be using using the server certificate (public key) and their own private key to make requests."* - this is not true. A client will create its own key pair (private and public key) and the public key will be part of the client certificate. – Steffen Ullrich May 09 '20 at 18:16

3 Answers3

1

So you have a JVM that wants to talk to a SSL endpoint. Few things need to fall in-place:

  • Your JVM must "trust" the server
  • Your JVM must offer an identity (certificate) that the server trusts
  • at least one Encryption algorithm must match

In your JVM Keystore is where you keep your identity: This is typically a JKS and should have a "PrivateKeyEntry". This PrivateKeyEntry is really a P12 import of your Key + a Signed certificate

This file goes as the KeyStore system property (and you need to provide the corresponding password... thats another can-of-worms)

For you to trust the other party (or parties) you must trust them. This means you either have their actual "Certificates" imported into your TrustStore JKS or import the corresponding CA cert (issuer certificate)

This file should go in as the TrustStore file in your JVM's system property (similar password story here)

Note: Nothing stops you from using the same JKS file as keystore and truststore. You just need to import your P12 and Trusted certificate entries in the same JKS file.

Now when you start the JVM and the client makes a REST call:

  1. Server will offer its identity
  2. Your client will offer its identity (this is what is set in your java keystore)
  3. You will lookup the identity offered by Server and check in your TrustStore. Here you will find either the same Subject entry or the Issuer's Subject entry
  4. Server does the same with your identity
  5. Both parties trust each other. They now negotiate a common Cipher
  6. Encrypt the channel using the Cipher

Note: the above steps are a rough explanation of SSL-handshake. If you need to get exact detail, you can lookup SSL handshake on wiki.

Now about your questions:

How to generate Private Key?

  • Use Keytool this will generate a self-signed key
  • If you do not have a CA then You would need to extract this certificate and send to your Server (else they can add the CA-cert or your signed cert)

Am I supposed to get a server certificate/public key?

Yes. If you care about trusting the server (usually a good idea)

If the answer to the above question is yes, then should I import that certificate to my keystore which I created and then use the keystore for communication?

Usually its a good-practice to keep your keystore separate from your trustStore. I would recommend putting your P12 (key + cert) in your keystore and the Server's certificate/public key in your truststore

Hope this helps :)

A G
  • 187
  • 7
  • 1
    JKS (Java KeyStore) is debatable, it is not the default anymore since Java 9 (PKCS12 a.k.a. P12 or PFX is) but PKCS12 was already supported before. see also: https://stackoverflow.com/questions/11536848/keystore-type-which-one-to-use – JohannesB May 09 '20 at 20:00
  • I have updated my question based on your response. I want to know if the key pair is required to be created in my case? If no, what would be the keystore and truststore in this case? – Samir Dutta May 10 '20 at 14:54
0

To answer your questions as a client of the REST API you should (with any tools you like, e.g.: Keystore Explorer or the Java provided: keytool):

  1. create a keypair (usually RSA 2048 bit) and store that in some kind of store (this could be a PKCS12/PFX file or for high security in hardware like an HSM)
  2. create an Certificate Signing Request (CSR) that includes the public key of your keypair and information about the client (like a DNS name, emailAddress, etc) and will be signed with your private key
  3. submit that CSR to the Certificate Authority that your REST API trusts (this could be a private internal Certificate Authority or a public one, just make sure it is trusted by the server)
  4. request from the certificate authority the right kind of certificate (an attribute called: "Extended/Enhanced Key Usage" should include: "Client Authentication", this may be combined with "Server Authentication" but in the interest of security you might want to seperate these responsibilities)
  5. import the certificate into your keystore (where the keypair resides) and configure your application to use this keystore
  6. start Java with -Djavax.net.debug=all and observe the applications interaction with the server, the server should prompt the client for a certificate and indicate with (a possibly empty) list which certificate authorities it trusts for signing client certificates (an empty list means any client certificate is fine)

See also lot's of similar questions from other users:

And if in doubt do not hesitate to read the relevant RFC for the details from an authoritive source:

depending on the version of the protocol there are some differences (client certificate may be requested during the initial handshake or afterwards during renegotiation (TLSv1.2) or with Post-Handshake Authentication (TLSv1.3) as renegotiation was removed from the new protocol. (But this is different for HTTP/2, see: https://www.rfc-editor.org/rfc/rfc8740.html )

Community
  • 1
  • 1
JohannesB
  • 2,126
  • 1
  • 10
  • 18
  • I have updated my question based on your response. I want to know if the key pair is required to be created in my case? If no, what would be the keystore and truststore in this case? – Samir Dutta May 10 '20 at 14:53
  • Yes you really need the whole keypair, both the private and public key, the private key is not transmitted but used to encrypt challenges that proof possession of the private key as proof of your identity as described in the client certificate that contains the public key. – JohannesB May 10 '20 at 15:34
  • For testing purpose/test environment, can I create a self signed client certificate? If so, do I need to share that with the server so that they can get it added to their truststore for mutual handshake? – Samir Dutta May 10 '20 at 16:13
  • Yes self signed might very well work the way you describe, all root certificate authorities are self signed – JohannesB May 10 '20 at 16:16
-1

It looks like you would required one way SSL. Here the client validates the server i.e. the server displays its public key for authentication to its client. In you case I suppose when you generate the SSL certificates with keystore, the application has the public key available to authenticate itself to the client and the private key to decrypt the communication encrypted with your public key. You can generate you keystore files in development but when moving to production use CA authorised certificates and import them into your keystore.

Vaibhav
  • 96
  • 7