Overview

In previous post, we hav learn basics of SSL/TLS. now we will see following things:

In some cases it may make more sense to act as your own CA, rather than paying a CA like DigiCert. Common cases include securing an intranet website, or for issuing certificates to clients to allow them to authenticate to a server (eg, Apache, OpenVPN).

Basics and terminologies of Certificates

Certificate Authority (CA)

Certificate Signing Request (CSR)

When you are going to request SSL certificate from trusted CA, then you require CSR (Certificate Signing Request). the CSR is encrypted text containing information about the certificate that needs to be requested. for each certificate request a new CSR is required. With a CSR you can request a certificate online.

What’s in a CSR?

A CSR consists of two parts:

1) Request information, such as the domain name en the Organisation Name. A digital signature with a keysize of at least 2048 bits.

Example of a CSR:

-----BEGIN NEW CERTIFICATE REQUEST-----

MIIDdDCCAt0CAQAwgYExCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhNaXNzb3VyaTEP

<meer regels met gecodeerde data>

3zxQMwtCDFdDbbKCN9gKalJkEGzqXrx9

-----END NEW CERTIFICATE REQUEST-----

2) Key Pair

When requesting a CSR, two keys will be saved on your server:

The Private Key must be kept secret and should at all times remain on the server. without the Private key the certificate does not work.

The Public Key will be added in the CSR and will be sent when ordering via our request form.

When all validation procedures are finished the Certification Authority (for example Comodo) digitally signs the CSR.

The issued certificate corresponds with the Private Key and can be validated with that while installing.

Setting up own CA

Now our use case is, we will setup own CA for internal use only. let say, you can have multiple https sites running with your own sign certificates. also you can encrypt communications between client and server using certificates. and it’s free :)

We are going to use cfssl tool to generate certificates.

Root Pair

Acting as a certificate authority (CA) means dealing with cryptographic pairs of private keys and public certificates. The very first cryptographic pair we’ll create is the root pair. This consists of the root key (ca.key) and root certificate (ca.pem). This pair forms the identity of your CA.

Typically, the root CA does not sign server or client certificates directly. The root CA is only ever used to create one or more intermediate CAs, which are trusted by the root CA to sign certificates on their behalf. This is best practice. It allows the root key to be kept offline and unused as much as possible, as any compromise of the root key is disastrous.

Create file ca-csr.json with following content:

{
  "CN": "Linuxian root CA",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
    "names": [
       {
         "C": "NL",
         "ST": "Netherlands",
         "L": "Amsterdam",
         "O": "Linuxian",
         "OU": "CA Services"
       }
    ]
}

Let’s generate root pair using :

mkdir ~/certs
chmod 0700 ~/certs
cd ~/certs
cfssl gencert -initca ca-csr.json | cfssljson -bare ca

It will generate three files.

Now, let’s verify the root certificate

openssl x509 -noout -text -in ca.pem

The output shows:

Let’s create CA configuration, which will provide profile for server and client.

Create file ca-config.json with following content:

{
  "signing": {
    "default": {
      "expiry": "8760h"
    },
    "profiles": {
      "server": {
        "usages": [
          "signing",
          "key encipherment",
          "server auth"
        ],
        "expiry": "8760h"
      },
      "client": {
        "usages": [
          "signing",
          "key encipherment",
          "client auth"
        ],
        "expiry": "8760h"
      }
    }
  }
}

Now if you want to sign certificates for your internal web server, for example vault.linuxian.local

Create file called server-csr.json with following content:

{
  "CN": "vault.linuxian.local",
  "hosts": [
    "vault.linuxian.local"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "NL",
      "L": "Amsterdam",
      "O": "Linuxian",
      "OU": "CA",
      "ST": "Netherlands"
    }
  ]
}

Sign server certificate with own Root CA:

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server server-csr.json |  cfssljson -bare server

Now you will have server public and private key.

Simple HTTPS server

Let’s use newly created certificates and run simple python https server to use it.

Create file simple-https-server.py as below:

#!/usr/local/bin python

import BaseHTTPServer, SimpleHTTPServer
import ssl

httpd = BaseHTTPServer.HTTPServer(('0.0.0.0', 443),SimpleHTTPServer.SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket(httpd.socket, certfile='./server.pem', keyfile='./server-key.pem', server_side=True, ssl_version=ssl.PROTOCOL_TLSv1_2)

httpd.serve_forever()

Run server :

sudo python simple-https-server.py

Make sure your domain should resolve to the ip where this server is running.

You will get error saying insecure site as below:

insecure site

You are getting this error because your server certificate is not sign by public trusted authority. and it’s sign by your own CA. but your own Root CA Public key, not exists in your trusted certificate. So you need to add Root Publice certificate ca.pem in trusted.

Once you added in trusted certificate, In my case for Mac OS, I’ve added ca.pem in Keychain access under login.

You will successfully see Green result :)

Secure site

Secure site2

Please feel free to comment below, if you find any difficulties