Run You Own Certificate Authority
Most websites, such as shopping, banking or email websites, need to let their customers know that the connection is secure. Thus, they need to pay a well-known and internationally trusted Certificate Authority (eg,VeriSign) to issue an SSL certificate. However, this isn’t always necessary. For example, if you’re setting up a virtual private network (VPN) or an intranet website, it might make more sense to issue your own certificates.
Being a Certificate Authority means dealing with cryptographic pairs of private keys and public certificates. Ideally the cryptographic pairs should be generated in a secure environment, which means a personal laptop or computer that is disconnected from the Internet. It is not recommended to generate any certificates directly on your server.
In this example, the /etc/CyberPunk/CA directory will be used to store all keys and certificates. The index.txt and serial files act as a kind of flat file database to help you keep track of all your keys and certificates.
Important: Ensure that your OpenSSL configuration file (/etc/CyberPunk/tls/openssl.cnf) specifiesdir=/etc/CyberPunk/CA within the [ CA_default ] section. Feel free to create your certificates within any other directory, as long as you change the dir= option to match.
cd/etc/CyberPunk/CA
mkdir certs crl newcerts private
chmod 700 private
touch index.txt
echo 1000 > serial
The very first cryptographic pair we generate includes what is known as a root certificate. The root key (ca.key.pem) generated in this step should be kept extremely secure, otherwise an attacker can issue valid certificates for themselves. We’ll therefore protect it with AES 256-bit encryption and a strong password just in case it falls into the wrong hands:
openssl genrsa -aes256 -out /etc/CyberPunk/CA/private/ca.key.pem 4096
Enter pass phrase for ca.key.pem: secretpassword
Verifying - Enter pass phrase for ca.key.pem: secretpassword
chmod 400 /etc/CyberPunk/CA/private/ca.key.pem
Open your OpenSSL configuration file (/etc/CyberPunk/tls/openssl.cnf) and look for the [ usr_cert ] and [ v3_ca ] sections. Make sure they contain the following options:
[ usr_cert ]
# These extensions are added when 'ca' signs a request.
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
nsComment = "OpenSSL Generated Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
[ v3_ca ]
# Extensions for a typical CA
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = CA:true
keyUsage = cRLSign, keyCertSign
Now you can use the root key above to issue a root certificate (ca.cert.pem). In this example, the certificate is set to expire in ten years. As this is a Certificate Authority certificate, use the v3_ca extension. You will be prompted for some responses, which you can fill with whatever you like. For convenience, defaults can be set in the openssl configuration file.
openssl req -new -x509 -days 3650 -key /etc/CyberPunk/CA/private/ca.key.pem \
-extensions v3_ca -out /etc/CyberPunk/CA/certs/ca.cert.pem
Enter pass phrase for ca.key.pem:
You are about to be asked to enter information that will be incorporated
into your certificate request.
-----
Country Name (2 letter code) [XX]:AQ
State or Province Name (full name) []:Antarctica
Locality Name (eg, city) [Default City]:TuX City
Organization Name (eg, company) [Default Company Ltd]:CyberPunk
Organizational Unit Name (eg, section) []:N0WHERE
Common Name (eg, your name or your server's hostname) []:N0WHERE NET
Email Address []:admin@n0where.net
chmod 444 /etc/CyberPunk/CA/certs/ca.cert.pem
Armed with your root key (ca.key.pem) and root certificate (ca.cert.pem), you are now ready to create an intermediate certificate authority or issue and sign your own SSL certificates
Intermediate Certificate
An intermediate certificate authority (CA) is an intermediary that can sign certificates on behalf of the root certificate authority. A certificate can be signed by the intermediate CA, which itself is signed by the root certificate authority, so a chain of trust is formed.
Having an intermediate certificate authority makes life more convenient in the event that your key is compromised. Using your root certificate authority, you can revoke your compromised intermediate certificate authority and create another. It also allows you to keep your root CA completely off-line (eg, on an encrypted USB) and you will only have to use your root key to revoke or renew your intermediate certificate.
If you are acting as your own certificate authority, you can easily create an intermediate certificate authority. You should have a root key and root certificate inside the /etc/CyberPunk/CA directory. Use a completely new directory to hold your intermediate certificate authority and any certificates that you sign with it. In this case, the directory tree is created in /etc/CyberPunk/CA/intermediate:
cd /etc/CyberPunk/CA/intermediate
mkdir certs crl newcerts private
chmod 700 private
touch index.txt
echo 1000 > serial
A different directory tree is being used, so you must let openssl know about this. First, copy your configuration file to the new directory:
cp /etc/CyberPunk/tls/openssl.cnf /etc/CyberPunk/CA/intermediate/openssl.cnf
Then ensure dir=/etc/CyberPunk/CA/intermediate is specified within the [ CA_default ] section of your new configuration file.
Important: Whenever you want to create and sign a certificate with your intermediate certificate authority, you must pass the -config /etc/CyberPunk/CA/intermediate/openssl.cnf option so that openssl knows which directory holds your intermediate certificate authority.
Now you can create the intermediate key. Like the root key, this should be kept very secure.
cd /etc/CyberPunk/CA
openssl genrsa -aes256 -out intermediate/private/intermediate.key.pem 4096
Enter pass phrase for intermediate.key.pem: secretpassword
Verifying - Enter pass phrase for intermediate.key.pem: secretpassword
chmod 400 intermediate/private/intermediate.key.pem
Using the intermediate key, create the intermediate CSR. Make sure the Organizational Name matches the one set for your root certificate authority. You can leave the extra attributes empty.
cd /etc/CyberPunk/CA
openssl req -config intermediate/openssl.cnf \
-new -key intermediate/private/intermediate.key.pem \
-out intermediate/certs/intermediate.csr.pem
Enter pass phrase for intermediate.key.pem: secretpassword
You are about to be asked to enter information that will be incorporated
into your certificate request.
-----
Country Name (2 letter code) [XX]:AQ
State or Province Name (full name) []:Antarctica
Locality Name (eg, city) [Default City]:TuX City
Organization Name (eg, company) [Default Company Ltd]:CyberPunk
Organizational Unit Name (eg, section) []:N0WHERE
Common Name (eg, your name or your server's hostname) []:N0WHERE NET
Email Address []:admin@n0where.net
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
You can now sign your intermediate CSR with your root certificate authority to issue an intermediate certificate. Use the v3_ca extension as this is a certificate authority certificate.
NB: Note that you can avoid having to specify -keyfile and -cert options by changing theprivate_key and certificate options in the [ CA_default ] section of your openssl configuration.
cd /etc/CyberPunk/CA
openssl ca -config intermediate/openssl.cnf \
-keyfile private/ca.key.pem \
-cert certs/ca.cert.pem \
-extensions v3_ca -notext -md sha1 \
-in intermediate/certs/intermediate.csr.pem \
-out intermediate/certs/intermediate.cert.pem
chmod 444 intermediate/certs/intermediate.cert.pem
To verify that your intermediate certificate is valid, run the following:
openssl verify -CAfile /etc/CyberPunk/CA/certs/ca.cert.pem \
/etc/CyberPunk/CA/intermediate/certs/intermediate.cert.pem
/etc/CyberPunk/CA/intermediate/certs/intermediate.cert.pem: OK
When an Internet browser or any other application tries to verify a certificate signed by your intermediate certificate authority, it will also need to verify the intermediate certificate against the root certificate. To do this, it will need a certificate chain file. This is created by simply concatenating your intermediate certificate and root certificate together:
cd /etc/CyberPunk/CA
cat intermediate/certs/intermediate.cert.pem \
certs/ca.cert.pem > intermediate/certs/ca-chain.cert.pem
chmod 444 intermediate/certs/ca-chain.cert.pem
At this point you are ready to issue and sign certificates using your intermediate certificate authority. To verify that certificates signed by your intermediate certificate authority are valid, you must test them against the certificate chain file:
openssl verify -CAfile /etc/CyberPunk/CA/intermediate/certs/ca-chain.cert.pem \
/etc/CyberPunk/CA/intermediate/certs/n0where.net.cert.pem
/etc/CyberPunk/CA/intermediate/certs/n0where.net.cert.pem: OK
Create and Sign SSL Certificates
If you’ve taken the necessary steps to become your own certificate authority, you are now in a position to issue and sign your own SSL certificates.
The first step is to create a private key. If your aim is to enable SSL on a web server, bear in mind that if the key is encrypted then you’ll have to enter the encryption password every time you restart your web server. Use the -aes256 argument if you wish to encrypt your private key.
If you have followed this tutorial through intermediate certificate authority setup you should navigate to/etc/CyberPunk/CA/intermediate in the following steps (If you skipped intermediate part you should stay in /etc/CyberPunk/CA).
cd /etc/CyberPunk/CA
openssl genrsa -out private/n0where.net.key.pem 4096
chmod 400 private/n0where.net.key.pem
The next step is to generate a certificate signing request (CSR). Normally, you would send your CSR to a trusted certificate authority (eg, VeriSign) who will then send you back a signed certificate in exchange for money. You can instead sign it yourself for free.
Make sure that the Organization Name you choose below matches the one set for your CA root certificate. The extra attributes can be left blank. If you are creating a self-signed certificate, you would also use the -x509 and -days options.
cd /etc/CyberPunk/CA
openssl req -new -key private/n0where.net.key.pem \
-out certs/n0where.net.csr.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
-----
Country Name (2 letter code) [XX]:AQ
State or Province Name (full name) []:Antarctica
Locality Name (eg, city) [Default City]:TuX City
Organization Name (eg, company) [Default Company Ltd]:CyberPunk
Organizational Unit Name (eg, section) []:N0WHERE
Common Name (eg, your name or your server's hostname) []:n0where.net
Email Address []:admin@n0where.net
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
As you are acting as your own certificate authority, you can use your certificate authority root key (ca.key.pem) and certificate authority root certificate (ca.cert.pem) to sign the CSR (n0where.net.csr.pem) and issue a new certificate (n0where.net.cert.pem).
NB: Note that you can avoid having to specify -keyfile and -cert options by changing theprivate_key and certificate options in the [ CA_default ] section of your openssl configuration.
cd /etc/CyberPunk/CA
openssl ca -keyfile private/ca.key.pem -cert certs/ca.cert.pem \
-extensions usr_cert -notext -md sha1 \
-in certs/n0where.net.csr.pem -out certs/n0where.net.cert.pem
chmod 444 /etc/CyberPunk/CA/certs/n0where.net.cert.pem
If you have followed the intermediate CA part then you can sign the CSR with your intermediate certificate authority instead. Just pass the -config /etc/CyberPunk/CA/intermediate/openssl.cnf option and change –keyfile and –cert to the intermediate key and certificate respectively.
The index.txt file is where the openssl ca tool stores the certificate database, so don’t delete it or edit it by hand! It should now contain a line referring to the certificate you just issued:
cat /etc/CyberPunk/CA/index.txt
V 140825154152Z 1000 unknown /C=AQ/ST=Antarctica/O=CyberPunk/OU=N0WHERE/CN=n0where.net/emailAddress=admin@n0where.net
You can verify the details of your certificate using openssl. Near the top of the output you will be able to see details of the issuer. This is the identity of the certificate authority that signed the certificate, which in this case is your own CA. The subject is the identity of the certificate you just signed:
openssl x509 -in n0where.net.cert.pem -noout -text
Certificate:
...
Issuer: C=AQ, ST=Antarctica, L=TuX City, O=CyberPunk CA, OU=N0WHERE, CN=N0WHERE NET/emailAddress=admin@n0where.net
...
Subject: C=AQ, ST=Antarctica, O=CyberPunk CA, OU=N0WHERE, CN=n0where.net/emailAddress=admin@n0where.net
...
You can also use openssl to verify the certificate against your root CA:
openssl verify -CAfile /etc/CyberPunk/CA/certs/ca.cert.pem \
/etc/CyberPunk/CA/certs/n0where.net.cert.pem
www.example.com.cert.pem: OK
You can now use your signed certificate for fun and profit! To allow a service (eg, Apache) to make use of your certificate, the following files need to be transferred to your server:
- ca.cert.pem
- n0where.net.key.pem
- n0where.net.cert.pem
Clients can install your root certificate (ca.cert.pem) into their Internet browser. All certificates signed by you will then be trusted by their browser and they will no longer see a This Connection is Untrusted message. It’s a good idea to create a detached signature for your root certificate with GnuPG; clients can then verify that the certificate they’re installing in their browser really is the correct one.
On Debian and Ubuntu you have to copy the certificate.pem to /usr/local/share/ca-certificates and then run update-ca-certificates. /etc/ssl/certs is managed by that command.
Create the CRL
Before we can generate a CRL, we must create a crlnumber file, which openssl requires to keep track of the next CRL number to use:
echo 1000 > /etc/CyberPunk/CA/crlnumber
By default, the openssl configuration file (/etc/CyberPunk/tls/openssl.cnf) uses V1 CRL lists. Uncomment the crl_extensions = crl_ext line to enable V2 CRL lists. This is probably a good idea unless you have a strong reason to stick with V1 CRL lists (eg, using an Internet browser from the Jurassic period). Now you can generate the CRL.
NB: Note that you can avoid having to specify –keyfile and –cert options by changing theprivate_key and certificate options in the [ CA_default ] section of your openssl configuration.
cd /etc/CyberPunk/CA
openssl ca -keyfile private/ca.key.pem -cert certs/ca.cert.pem \
-gencrl -out crl/crl.pem
You can view the CRL with this command:
crl -in /etc/CyberPunk/CA/crl/crl.pem -text
There are several other CRL options that can be used when generating your CRL list. See the CRL OPTIONS section in the ca manual page (man ca) for more information.
Revoke the certificate
cd /etc/CyberPunk/CA
openssl ca -keyfile private/ca.key.pem -cert certs/ca.cert.pem \
-revoke certs/bad.certificate.cert.pem
If you take another look at the index.txt database, you’ll see that the V at the start of the line has changed to an R, which means the certificate has been revoked.
cat /etc/CyberPunk/CA/index.txt
R 140825183639Z 130825184208Z 1000 unknown /C=AQ/ST=Antarctica/O=CyberPunk CA/OU=N0WHERE/CN=badcertificate.net/emailAddress=admin@n0where.net
Note that newly created certificates are also placed in the /etc/CyberPunk/CA/newcerts directory, with a filename that matches the serial number in index.txt.
Update the CRL
Now that badcertificate.net certificate has been revoked, we need to re-generate the CRL:
cd /etc/CyberPunk/CA
openssl ca -keyfile private/ca.key.pem -cert certs/ca.cert.pem \
-gencrl -out crl/crl.pem
Let’s take another look at the CRL:
openssl crl -in /etc/CyberPunk/CA/crl/crl.pem -text
Certificate Revocation List (CRL):
...
Revoked Certificates:
Serial Number: 1000
...