Mutual authentication to end point fails with javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificateProblem
When establishing SSL connections to 3rd party end-points, the default settings on the instance httpclient protocol could interfere with their defined handshake.
- When a client requests the server certificate for authentication, a certificate signing request (CSR) is generated.
- To respond to a CSR, the server generates two unique cryptographic keys: A public key, which is used to encrypt messages to the server and a private key, which is used to decrypt messages. Both keys are kept in the Key Store.
- Keys are used to decrypt the client secure messages so they can be read by the server. Any outgoing connection that is going to be HTTPS verifies the certification by checking the Key Store, offering its public certification, and uses the trust store certificates to verify mutual trust back.
- To complete the secure link between the client and the server, the server matches the certificate to the corresponding private key. Because only the server has access to the private key, the server can decrypt the data from the client.
The problem appears if these settings do not match with the end-point setup, and you could receive an error of bad_certificate
You will have this problem if:
- Connections to the system using non-mutual authenticated services works fine.
- You have multiple keystore installed.
- Testing on SOAP UI or other tools against the mutual authenticated end-point, you've also received a bad_certificate error.
- Setting the properties to empty, or to match the end-point setup for SSL handshake resolves the problem.
There are several possible reasons.Here is an example of a command that registers MYHTTPS with the
com.glide.certificates.DBKeyStoreSocketFactory socket factory on port 443. The database key store factory is used during the SSL exchange process to offer a client certificate for mutual authentication.
glide.httpclient.protocol.myhttps.class = "com.glide.certificates.DBKeyStoreSocketFactory" glide.httpclient.protocol.myhttps.port = "4433"
On this case if the end-point SSL socket factory is different to 4433, it could fail with an error.
On sys_properties form, set the value of glide.httpclient.protocol.myhttps.class and glide.httpclient.protocol.myhttps.port, to empty. If this does not work, match your mutual authentication profile value accordingly to the setup for your end-point.
Once you have uploaded the CA-signed certificate to the instance of your end-point, and you have created separate certificate records for them, you should simply update the key-store reference field on the existing myhttps protocol profile. If you create another protocol profile for the testing or the production environment, you might run into connection errors when trying to connect to the target system. Therefore, in order to prevent some unexpected behavior, keep only one protocol profile named myhttps, and simply update the references to the CA-signed key-store. Also, make sure the key-store file name contains only small letters, as you might end up having authentication issues.
|Note: Overriding the default HTTPS protocol socket factory affects every outbound HTTPS connection. This is usually undesirable.|