What is a certificate?
Certificate represents an identity of any entity. An entity could be a person, host, application. In real world, I relate passport to a certificate. A passport is valid only when a passport issuing authority approves a passport request. This is a valid passport because passport issuing authority is trusted. With a trusted authority issuing a passport, this passport becomes an identity of the requesting entity, a certificate. Of course, authority requires a fees to be paid to validate the passport request before issuing one.
What is a self signed certificate?
In cryptography and computer security, self-signed certificates are public key certificates that their users issue on their own behalf, as opposed to a certificate authority (CA) issuing them.
[ do not try this at home :-) ] Issuing your passport by your own self is a typical example I relate self signed certificate with. No authority is going to accept a self issued passport. Consider yourself spared if you even tried and not face legal issues. Issuing your own passport has no valid use case in real world. But a self signed certificate has a few use cases like it can be used in application development phase, no signing authority (CA) is involved - so no wait time on the authority to certificate approved and no cost involved.
Never use a self signed certificate in a production system.
How to create self signed certificate?
There are tools available to create self signed certificate - keytool
and openssl
are popular ones. In this blog, I will use keytool
which is provided with jdk. openssl
can also be used but the steps would be different. I will assume that I have a web application hosted in my local machine. This application should be serving HTTP requests over ssl - HTTPS. Let's create a self signed certificate by running the following command.
keytool -storetype pkcs12 -keystore sks.p12 -storepass manage \
-alias server_key_rsa -keyalg rsa \
-genkeypair \
-dname "CN=is, OU=rnd, O=sag, L=ba, ST=ka, C=in" \
-ext ku=digitalsignature,keyencipherment,dataencipherment,keycertsign \
-ext bc=ca:true \
-ext san=dns:localhost
Explanation of the options used.
Option | Description |
---|---|
-storetype pkcs12 | Defines type of the keystore. Either pkcs12 or jks. |
- keystore sks.p12 | Defines name of keystore file. Ex: sks.p12. Keystore file could be any name. A new file is created if one mentioned is not present. |
-storepass manage | Defines the password for the store. |
-keyalg rsa | Defines the algorithm to create the keypair. |
-alias server_key_rsa | Defines an alias for the keypair in a keystore. A keystore can have many key pairs, each of them uniquely identified by an alias. Ex: server_key_rsa. |
-genkeypair | Command to create keypair. |
-dname "CN=is, OU=rnd, O=gas, L=ba, ST=ka, C=in" | Defines distinguished name for the entity. |
-ext ku=digitalsignature,dataencipherment,keycertsign | For a self signed certificate, key usage (ku) should have keycertsign and digitalsignature as the primary generated by the entity will be used to sign its own public certificate. |
-ext bc=ca:true | Defines certificate entity as ca. |
-ext san=dns:localhost | Defines server name as localhost. It is also possible to localhost in CN and clients could accept but it is more clear to define the dns as localhost to be explicit while the name of application can be used in CN. |
Now, we have a keystore (sks.p12) with a keypair identified by alias 'server_key_rsa'. This keystore should be configured in java server application to server HTTP over ssl. I wont be getting into how to configure keystore in java application to server HTTPS.
Extracting self signed cert
Let's assume application is serving HTTPS on port 5443. I use curl
and httpie
. On firing curl https://localhost:5443
, there is an ssl error.
Curl
connected to https port. Server sent the certificate, a self signed one which curl does not trust simply because there is no issuing authority involved.
Fixing the client to accommodate self signed certificate
I know that the server is using a self signed certificate and this is not a production system. So, I want the client to work with it. That leaves two options.
- Ignore ssl verification
curl | httpie |
---|
curl https://localhost:5443 --insecure
|
http https://localhost:5443 --verify no
- Get the server certificate which was prepared with
-ext bc=ca:true
to be used as a mocked ca cert.
Refresh the keystore command we used to create the keypair. The alias we use is server_key and we need a server certificate. Use the below command to extract the server certificate.
keytool -export -rfc -keystore sks.p12 -alias server_key_rsa --storepass manage -file server_key_rsa_ca.pem
Most of the command options, by now, are already defined are familiar. Option -rfc
defines the format of the certificate to be rfc format. Now, server certificate is exported to a file server_key_rsa_ca.pem. Feel free to try out keytool -printcert -file server_key_rsa_ca.pem
to view the content of certificate.
curl | httpie |
---|
curl https://localhost:5443 --cacert server_key_rsa_ca.pem
|
http https://localhost:5443 --verify server_key_rsa_ca.pem
Now, the self signed certificate sent by the server is validated against the server certificate and request passes through.
This is how I got self signed certificate created, configured and used it in the client to test.
I put this blog up as I went through a lot of articles to get the self signed working with server and client by accepting the certificate. While this is a reference to the future me, I hope this article helped you as well.
Now, leave your experience with self signed certificate for me to learn !!
Top comments (0)