Self-Signed SSL Certificates for REST Development
Security can be a big concern when you are developing APIs that are exposed to the outside world. Best practice dictates that you should use SSL/TLS to secure your endpoints by encrypting the traffic if you are dealing with any sensitive information. SSL (Secure Sockets Layer) is a global standard security technology that encrypts the data being transmitted and authenticates the identity of the website. TLS (Transport Layer Security) is actually the newer replacement of SSL, but most people are more familiar with the historic term SSL so you may see that term used even though it actually may be TLS as the protocol. Standard HTTP traffic is unsecured and sent in clear text, but HTTPS adds a layer of security by using an SSL/TLS protocol connection to encrypt the data being sent.
SSL Certificate Overview
To ensure that the server is actually what it claims to be, an SSL certificate issued by a trusted third party is used to validate the claim. This third party is called a certificate authority (CA) and there are a number of major recognized companies such as Verisign, GeoTrust, and Comodo that provide this service. These companies will verify the identity of the company/person requesting the certificate, and in turn, when they sign your SSL certificate with their root CA certificate your browser will trust that certificate.
In production, you should obtain and install a certificate from one of the major CAs. Most of these major root CA certificates are included in your local trust store by default, so if an SSL certificate is signed by one of these, your browser will accept its authenticity and continue normal operation with the HTTPS connection. However, there are sometimes cases where you don’t necessarily need the recognition and cost of an official certificate. For example, if you are working in a development environment and you just need to make sure that your application works with SSL/TLS, you can “self-sign” your own certificates.
Become Your Own Certificate Authority
You could create a specific certificate for each required server, but then you have to add each individual SSL certificate into your trust store every time you create a new one. Another option is to become your own CA, and once you install that root certificate, any other SSL certificate you sign with that one will be trusted.
Programs You Need
There are a couple of OS utilities you will need to generate all the necessary keys and certificates. The latest UniData and UniVerse releases also include some Basic functions that will help you create certificates, but in this post we are focusing on the underlying technology so you can understand what is happening. You can also read this blog post about the Certificate Management Tool, which hides some of this complexity from you with a set of scripts to walk you through some key generation tasks.
- openssl – Utility from OpenSSL toolkit used for key management. This is provided in the U2 bin directory.
- keytool – Java keytool is a key and certificate management utility. Should be in JRE bin directory.
Create Your Root CA Certificate
You will be asked a set of questions to define this certificate. This is the information that will be seen when you view the details of this certificate. Because I will be using this certificate to sign other SSL certificates, I will just use my name as the Common Name so that I can recognize it when looking at my list of trusted certificates.
Note: I am using the bash shell on Windows for this demo
# Create your private key openssl genpkey -algorithm RSA -out myprivate.key -pkeyopt rsa_keygen_bits:2048 # # Generate root CA certificate openssl req -x509 -new -nodes -key myprivate.key -sha256 -days 1825 -out root_ca.crt # You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank. For some fields there will be a default value. If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:Colorado Locality Name (eg, city) :Denver Organization Name (eg, company) [Internet Widgits Pty Ltd]:Rocket Software Organizational Unit Name (eg, section) :CSE Common Name (e.g. server FQDN or YOUR name) :Michael Byrne Email Address :firstname.lastname@example.org
You should now see your root CA certificate created in the file root_ca.crt!
Create an SSL Certificate for the Server
Now that we have our root CA certificate, we can move on to creating our first server SSL certificate and sign it with this root CA certificate.
It is important to note, support for the Common Name attribute was deprecated in RFC 2818 since 2000 officially, but for many years browsers did not enforce this setting. However, as of Chrome 58 and Firefox 48, the Common Name value is ignored and you will start getting errors unless you use the subjectAltName x509 extension.
Because we need to add extended X509 attributes to this certificate, we can no longer rely on the prompts and we need to use a config file. As you can see below, I am creating a temporary config file with all the necessary information included that we then supply to the openssl utility. The key part of the extensions is the subjectAltName, this must specify a value with DNS and the name of the server from which HTTPS requests will be served.
# Build a config file for the server certificate cat > us-l-mb02.conf <<EOF [req] distinguished_name = req_distinguished_name prompt = no # [req_distinguished_name] countryName = "US" # C= stateOrProvinceName = "Colorado" # ST= localityName = "Denver" # L= organizationName = "Rocket Software" # O= organizationalUnitName = "dev" # OU= commonName = "us-l-mb02" # CN= emailAddress = "email@example.com" # CN/emailAddress= # [v3_ext] basicConstraints = CA:FALSE nsCertType = server nsComment = "OpenSSL Custom Generated Server Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth subjectAltName = DNS:us-l-mb02 EOF # # Create the CSR (Certificate Signing Request) for server openssl req -new -key myprivate.key -config us-l-mb02.conf -out us-l-mb02.csr # # Create SERVER certificate openssl x509 -req -in us-l-mb02.csr -CA root_ca.crt -CAkey myprivate.key -CAcreateserial \ -out us-l-mb02.crt -days 1825 -sha256 -extensions v3_ext -extfile us-l-mb02.conf # # Delete the temporary config file rm us-l-mb02.conf
At this point, we have the three pieces we need to now create our server certificate:
- myprivate.key – The private key used to create both the CA Certificate and the CSR
- root_ca.crt – The root certificate we will sign with
- us-l-mb02.crt – The server SSL certificate for our development machine
Using the commands below, we package the CA and server certificate into a PKCS12 certificate. Then we finally create the key store using the keytool utility. The key store (keystore.jks) is what our REST server will use to provide HTTPS for our APIs.
# NOTE: You may need to precede openssl commands with winpty on windows bash("winpty openssl ....") # Package the CA and server certificates into a PKCS12 certificate winpty openssl pkcs12 -export -out certificate.pfx -passout pass:password \ -inkey myprivate.key -in us-l-mb02.crt -certfile ca.crt # # Import the PKCS certificate into the java keystore keytool -importkeystore -deststorepass password -destkeystore keystore.jks \ -srckeystore certificate.pfx -srcstorepass password -srcstoretype PKCS12
Configure U2 REST Server for HTTPS
At this point, we are ready to configure our U2 REST server to require HTTPS connections. To do this, right-click on your REST server in the RESTful Web Services Developer and choose Properties. Make sure all your information is correct then click Next to get to the REST Server Connection Security panel. Check the Use SSL box and then browse to find where your keystore.jks file is located. If you followed the commands above, enter “password” in the key store password fields. Click Finish to save your changes and then start your REST server by right-clicking and selecting “Start REST Server”. Your REST server now requires an HTTPS connection for all connections and uses your key store when clients check which certificates they trust.
At this point, if you were to try to hit the REST API with your browser, you will see a page like the following.
This is because we have not configured Chrome to trust certificates that were signed with our root certificate. To do this in Chrome, open a new tab and go to chrome://settings, go to the bottom and click Advanced, then find and click Manage Certificates. This should bring up the Windows Certificate management panel. Click on the Trusted Root Authorities tab and then click on Import. Click Next and then browse to find where you stored your root_ca.crt file. Keep clicking Next and then Finish to import the certificate.
Now you’re ready to access your REST API securely. Close all your browsers and restart, then go back to your REST URI and you should see the API results as well as the secure lock icon in the upper left of the location bar. Congratulations!