Skip to main content

How to setup your own CA and sign your digital certificates

Openssl is a cryptographic library that can be used to generate digital certificates. In this blog, I will walk you through the process of creating a Root CA and signing the generated digital certificates with them.

For a quick primer on digital certificates take a look at this article.

To begin with lets generate a Root CA. This process will require generating a CA private key and a CA certificate.

Generate a 4096 bit long RSA key for Root CA

$ openssl genrsa -out rootCA.key 4096 
Generating RSA private key, 4096 bit long modulus .........++ .............................++ 
e is 65537 (0x010001)

Generate Root CA certificate 

$ openssl req -x509 -new -key rootCA.key -sha256 -days 1825 -out rootCA.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]:IN
State or Province Name (full name) [Some-State]:Karnataka
Locality Name (eg, city) []:Bangalore
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Sarath Systems Private Ltd
Organizational Unit Name (eg, section) []:Research & Development
Common Name (e.g. server FQDN or YOUR name) []:Sarath Systems Digital Certification Authority
Email Address []:xxxxxxxx@gmail.com  
-days 1825 : Certificate is valid for 5 years

Alternatively, you can use the following syntax for scripting:

openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1825 -subj "/C=IN/ST=Karnataka/L=Bangalore/O=Sarath Systems/OU=Research & Development/emailAddress=xxxxxxxx@gmail.com/CN=Sarath Systems Digital Certification Authority" -out rootCA.crt 

At the point, the Root CA certificate is generated and is ready to be used. We will proceed next to generate the server's Public & Private keys and sign them with the Root CA certificate.

Generate a 4096 bit long RSA based Server Private Key

$ openssl genrsa -out server.key 4096
Generating RSA private key, 4096 bit long modulus
..................................................................................................................................++
......................................++
e is 65537 (0x010001) 

Generate a CSR (Certificate Signing Request) which is then sent to the CA to be signed by the RootCA.

$ openssl req -new -key server.key -out server.csr
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]:IN
State or Province Name (full name) [Some-State]:Karnataka
Locality Name (eg, city) []:Bangalore
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Sarath Systems
Organizational Unit Name (eg, section) []:Cloud Security Business Unit
Common Name (e.g. server FQDN or YOUR name) []:Cloud Security
Email Address []:xxxx@sarathsystems.com 

Alternatively you can use the following syntax for scripting

openssl req -new -key server.key -subj "/C=IN/ST=Karnataka/L=Bangalore/O=Sarath Systems/OU=Research & Development/emailAddress=xxxxxxxx@in.ibm.com/OU=Cloud Security Business Unit/CN=Cloud Security" -out server.csr 

Generate a signed Server Public Certificate using the CSR and the RootCA

Before we can do this we need to understand a few changes to certificates that happened recently. As of 2000, support for CommonName in the certificates has been dropped and Subject Alternate Name (SAN) has become standardized. The latest versions of Firefox/Chrome look at the SAN field to validate a certificate.

In order to generate a certificate with SAN, we can supply the necessary parameters via a config file. In our case, lets create a file called cert.config with the following data:
authorityKeyIdentifier=keyid,issuer 
basicConstraints=CA:FALSE 
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment 
subjectAltName = @alt_names 

[alt_names] 
DNS.1 = www.mywebsite.com 
DNS.2 = www.mywebsite-alternate-dns.com 
IP.1 = 192.168.56.101  -- An ip address you want to bind the certificate to [optional]

Now generate the Server's Public Key

$ openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server.crt -days 1825 -sha2
56 -extfile cert.config
Signature ok
subject=C = IN, ST = Karnataka, L = Bangalore, O = Sarath Systems Private Ltd, OU = Cloud Security Business Unit, CN = Cloud Security, emailAddress = xxxxxx@sarathsystems.com
Getting CA Private Key 

Try it out

If you have docker on your system, you can try out a demo container I have written to demonstrate the root CA generation and Server certificate signing by following the instructions @ https://hub.docker.com/r/sarathmekala/pkcsdemo

Further reading:

Comments

Popular posts from this blog

Openstack : Fixing Failed to create network. No tenant network is available for allocation issue.

Assumptions : You are using ML2 plugin configured to use Vlans If you try to create a network for a tenant and it fails with the following error: Error: Failed to create network "Test": 503-{u'NeutronError': {u'message': u'Unable to create the network. No tenant network is available for allocation.', u'type': u'NoNetworkAvailable', u'detail': u''}} The problem can be due to missing configuration in the below files: In /etc/neutron/plugins/ml2/ml2_conf.ini network_vlan_ranges =physnet1:1000:2999 (1000:2999 is the Vlan range allocation) In /etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini bridge_mappings = physnet1:br-eth1 (in OVS we map the physical network to the OVS bridge) Note You should have created a bridge br-eth1 manually and mapped it to a port ovs-vsctl add-br br-eth1 ovs-vsctl add-port br-eth1 eth1 Once configuration is done, restart the neutron ovs agent on the compute node(s):

Solved: Fix for Git clone failure due to GnuTLS recv error (-9)

My devstack installation was failing with an error reported by the GnuTLS module as shown below: $ git clone https://github.com/openstack/horizon.git /opt/stack/horizon --branch master Cloning into '/opt/stack/horizon'... remote: Counting objects: 154213, done. remote: Compressing objects: 100% (11/11), done. error: RPC failed; curl 56 GnuTLS recv error (-9): A TLS packet with unexpected length was received. fatal: The remote end hung up unexpectedly fatal: early EOF fatal: index-pack failed The following Git config changes fixed the issue for me. Am hoping it will be useful for someone out there: $ git config http.sslVerify false $ git config --global http.postBuffer 1048576000

QuickBite: Tap Vs Veth

Linux supports virtual networking via various artifacts such as: Soft Switches (Linux Bridge, OpenVSwitch) Virtual Network Adapters (tun, tap, veth and a few more) In this blog, we will look at the virtual network adapters tap and veth. From a practical view point, both seem to be having the same functionality and its a bit confusing as to where to use what. A quick definition of tap/veth is as follows: TAP A TAP is a simulated interface which exists only in the kernel and has no physical component associated with it. It can be viewed as a simple Point-to-Point or Ethernet device, which instead of receiving packets from a physical media, receives them from user space program and instead of sending packets via physical media writes them to the user space program. When a user space program (in our case the VM) gets attached to the tap interface it gets hold of a file descriptor, reading from which gives it the data being sent on the tap interface. Writing to the file descri