We have a server and a client. Connecting via SSL / TLS protocols, in addition to encrypting the transmitted data, implies the client’s confidence that he is connected to the server he wanted. To do this, the server needs to go through the authentication procedure (show the passport). This mechanism is called one-way SSL.
There are cases when both the server and the client show passports to each other. This mechanism is called two-way SSL.
There are two possible options for obtaining certificates:
- Self generation. It’s free. Suitable if it is possible, when you have ability to install keystore (certificate store) and truststore (store of trusted certificates) in the server and in the client.
- Purchase from a renowned CA. Certification Authority usually is a well-known organization that is trusted by major software vendors. In some cases, we can create a CA ourselves, this refers to the first option. The server / client is likely to trust the certificate issued by the CA, so using a custom trustsore (there is a standard one) is not required.
The used certificates must be signed by other certificates called root certificates.
Sometimes, in a test environment, we can use self-signed certificates, for which they themselves are the root. In the target case, the root certificate is a CA certificate:
- When generating our certificate, we sign it with the root certificate of the CA created in this process;
- If you buy a certificate, it will already be signed by the root certificate of a well-known company.
In order for the server / client to trust our certificate, they must trust the CA. There is a database of root-CA certificates that we can trust. In the case of Java, the file is called cacerts. You can be found it by using this instruction.
To install a purchased certificate, you must specify the containing certificate store (jks, keystore file). If we generated a certificate by signing it with the root certificate of our own CA, then in addition to specifying the store with the certificate, it is necessary to create and specify the trust store by adding the root CA certificate there.
Creating a certificate store (keystore)
keytool -genkey -alias bmc -keyalg RSA -keystore server_keystore.jks -keysize 2048
New CA certificate and key to it
openssl req -new -x509 -keyout server-ca-key -out server_ca_cert
Create a Certificate Request (CSR)
keytool -keystore server_keystore.jks -alias bmc -certreq -file server_cert_file
Creating a signed certificate based on the CA certificate, its key and request
openssl x509 -req -CA server_ca_cert -CAkey server-ca-key -in server_cert_file -out server_cert_signed -days 365 -CAcreateserial -passin pass: qwe123
Importing the CA certificate into the keystore
keytool -keystore server_keystore.jks -alias CARoot -import -file server_ca_cert
Importing a signed certificate into a key store
keytool -keystore server_keystore.jks -alias bmc -import -file server_cert_signed
Create a trusted key store and import the root CA certificate into it
keytool -keystore client_truststore.jks -alias bmc -import -file server_ca_cert
As you can see from the commands, the process of signing the certificate by the root CA cert involves using the CSR – Certificate Signing Request. You can learn more about this from other sources.
At some stages of generation, you will be prompted to enter a password. At first, to avoid confusion, I recommend setting the same password combination in all cases. The example above uses qwe123.
In addition to the password, you will need to enter the value of the CN field. This field must match the name of the host where you intend to use the certificate. When generating certificates for testing purposes, the remaining fields can be filled in as you like.
As a result of executing the commands, 2 files will be obtained: server_keystore.jks and client_trustore.jks.
First, you need to generate certificates for one-way SSL as described above. Then repeat everything the same, but “vice versa”: generate a certificate store for the client client_keystore.jks and a trust store for the server server_truststore.jks. I give the commands below without comments, because they are exactly the same as those given above. Only the names of the files differ:
keytool -genkey -alias bmc -keyalg RSA -keystore client_keystore.jks -keysize 2048 openssl req -new -x509 -keyout client-ca-key -out client_ca_cert keytool -keystore client_keystore.jks -alias bmc -certreq -file client_cert_file openssl x509 -req -CA client_ca_cert -CAkey client-ca-key -in client_cert_file -out client_cert_signed -days 365 -CAcreateserial -passin pass: qwe123 keytool -keystore client_keystore.jks -alias CARoot -import -file client_ca_cert keytool -keystore client_keystore.jks -alias bmc -import -file client_cert_signed keytool -keystore server_truststore.jks -alias bmc -import -file client_ca_cert
As a result of executing the commands given in the 2 sections above, 4 files are obtained: server_keystore.jks, server_trustore.jks, client_keystore.jks, client_trustore.jks.
If you still have any questions, feel free to ask me in the comments under this article, or write me on firstname.lastname@example.org.