I am calling an HTTPS URL through a Java program. Does my Java client need to provide a certificate to the server to establish this connection? In other words, do I need my own certificate or is the server's certificate (which contains its public key) enough?
3 Answers
Depends what you are doing, and what you want to verify. If you are accessing data, and want to be sure that the server which knows the corresponding private key is the one sending you data (e.g. you're accessing a web page), you don't need your own certificate.
If the server wants to be able to verify that the client is a pre-defined one, which knows a private key corresponding to a public key recognised as a valid source, your client will need a certificate. This tends to be used when a pair of servers are communicating - they each sign the data with their own private key, and can verify that the data is coming from a known source by checking against public keys. It can also be used with some APIs, where only specific clients are intended to access.
At a guess, therefore, you don't need your own certificate for your client - it's generally fairly well documented by the server if you do.
- 27,263
- 7
- 89
- 101
-
With regard to predefined communication, can this also be achieved by the client raising a CSR which is signed by the server's CA and subsequently expecting the signed certificate in every API request? – kaizenCoder Sep 22 '18 at 10:16
Generally, most web servers running HTTPS do not require the client to have a certificate. If the server requires the client to authenticate, this is often done through credentials (e.g. username and password).
However, the converse is generally not true - i.e. most clients DO require web servers to have a valid certificate signed by a recognized CA. It is the responsibility of the client to check that the certificate is valid - otherwise the client has no way to be sure that they are in fact connected to the server it intended to connect to, and that it is not being MITM'd.
- 21,098
- 2
- 47
- 66
No. I've tried it and the client definitely does not need a certificate or predefined key.
Rather, after receiving a public key (which is part of the certificate) from the server, the client makes up a secret 'on the fly' and encrypts it with the public key from the server's certificate. The client sends the encrypted secret to the server as part of the handshake. Only the server can decrypt the message containing the secret from the client so long as only the server has the private key corresponding to the public key it sent in the certificate. Both client and server then use the securely transmitted secret to continue the conversation.
Client keys are only necessary when the server needs to confirm the identity of the client; in that case the client and server may communicate by transmitting messages encrypted with each others' public keys instead.
You can see this in action by running your code with the following jvm option:
Djavax.net.debug=ssl,handshake
The client and server may agree on a number of different cipher systems by which to exchange and then use the made-up secret; on my testbed it defaulted to Elliptic Curve encryption, as described at
https://commandlinefanatic.com/cgi-bin/showarticle.cgi?article=art060
- 51
- 1
- 1
-
1The TLS protocol underlying HTTPS does in fact allow the server to require a client to present a valid certificate in order to connect, just as the server supplies one to the client. Most of the time on user-facing websites this is not done but as other answers indicate, there are situations where it is useful. – Ben Sep 07 '18 at 14:38
-
1Yes that's right. Perhaps rather than a flat-out 'No', I should have written 'Not unless the server requires one'. I don't know of any https servers that actually require one though, which was the OP's original question. – Matt Sep 11 '18 at 12:17