This article will show you how to set up a Certificate Authority with OpenSSL. Digital certificates are documents used to prove the ownership of a public key. For example, a digital certificates is used to authenticate an accessed website via HTPS. Another example of a common use are document signing.
Certificates includes information about the key, identity of its owner, and the digital signature of an entity that has verified the contents. A certificate authority (CA) is the organization that issues digital certificates.
Also this article will show how to tell other hosts to trust the certficates issued.
Warning: this should be only for testing purposes or proof of concept. For real-life uses you should acquire real certificates from a real certificate authority. For instance if you just want HTTPS and want the certificate for free, just go to https://letsencrypt.org/
Install OpenSSL
My main OS is FreeBSD, and I like to use the ports tree, to install it just run:
# cd /usr/ports/security/openssl
# make install clean
And wait until the compile and installation of the port is ready. Pay attention that you probably already have an openssl executable (under /usr/bin path) and if you install it anyway the ‘port’ binary will be at /usr/local/bin/openssl.
The first time I dealt with OpenSSL, the binary provided didn’t worked for me but the port does.
Configuration file
Although my main OS is FreeBSD, from now on, should be the same steps on any OS that support OpenSSL. Maybe you need to adjust some paths but that’s all.
You’ll find (again, in FreeBSD) an example and well commentend configuration file in /usr/local/openssl/openssl.conf. This is mine after some cleanup, I’ve highlighted the most important settings:
#OpenSSL Home current directory HOME = /var/openssl #choose any reasonable location #RANDFILE = $ENV::HOME/.rnd # Extra OBJECT IDENTIFIER info: oid_section = new_oids [ new_oids ] tsa_policy1 = 1.2.3.4.1 tsa_policy2 = 1.2.3.4.5.6 tsa_policy3 = 1.2.3.4.5.7 [ ca ] default_ca = YourCA # The default Certificate Authority section [ YourCA ] #most important section of your file dir = /var/openssl/yourCA # Where everything is kept # choose any reasonable location certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crl # Where the issued crl are kept database = $dir/index.txt # database index file. new_certs_dir = $dir/newcerts # default place for new certs. certificate = $dir/CA/yourCA.crt # The CA certificate serial = $dir/serial # The current serial number #crlnumber = $dir/crlnumber # the current crl number # must be commented out to leave a V1 CRL crl = $dir/CA/yourCA.crl # The current CRL private_key = $dir/CA/yourCA.key # The private key RANDFILE = $dir/private/.rand # private random number file x509_extensions = usr_cert # The extentions to add to the cert # Comment out the following two lines for the "traditional" # (and highly broken) format. name_opt = ca_default # Subject Name options cert_opt = ca_default # Certificate field options default_days = 365 # how long to certify for default_crl_days= 30 # how long before next CRL default_md = default # use public key default MD preserve = no # keep passed DN ordering policy = policy_match # For the CA policy [ policy_match ] countryName = match stateOrProvinceName = supplied organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional localityName = supplied # For the 'anything' policy. At this point in time, you must list all # acceptable 'object' types. [ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional ############################################################ [ req ] default_bits = 2048 default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes x509_extensions = v3_ca # The extentions to add to the self signed cert string_mask = utf8only [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = AR #I'm on ARgentina countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = Salta # i.e. the province I live on localityName = Locality Name (eg, city) 0.organizationName = Organization Name (eg, company) 0.organizationName_default = Your company name organizationalUnitName = Organizational Unit Name (eg, section) organizationalUnitName_default = Section Name. # eg. IT commonName = Common Name (e.g. server FQDN or YOUR name) commonName_max = 64 emailAddress = Email Address emailAddress_max = 64 [ req_attributes ] challengePassword = A challenge password challengePassword_min = 4 challengePassword_max = 20 unstructuredName = An optional company name [ usr_cert ] basicConstraints=CA:FALSE nsComment = "OpenSSL Generated Certificate" subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer [ v3_req ] # Extensions to add to a certificate request basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment [ v3_ca ] # Extensions for a typical CA # PKIX recommendation. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer basicConstraints = CA:true [ crl_ext ] authorityKeyIdentifier=keyid:always [ proxy_cert_ext ] basicConstraints=CA:FALSE nsComment = "OpenSSL Generated Certificate" subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer # This really needs to be in place for it to be a proxy certificate. proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo [ tsa ] default_tsa = tsa_config1 # the default TSA section [ tsa_config1 ] # These are used by the TSA reply generation only. dir = ./demoCA # TSA root directory serial = $dir/tsaserial # The current serial number (mandatory) crypto_device = builtin # OpenSSL engine to use for signing signer_cert = $dir/tsacert.pem # The TSA signing certificate # (optional) certs = $dir/cacert.pem # Certificate chain to include in reply # (optional) signer_key = $dir/private/tsakey.pem # The TSA private key (optional) default_policy = tsa_policy1 # Policy if request did not specify it # (optional) other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional) digests = md5, sha1 # Acceptable message digests (mandatory) accuracy = secs:1, millisecs:500, microsecs:100 # (optional) clock_precision_digits = 0 # number of digits after dot. (optional) ordering = yes # Is ordering defined for timestamps? # (optional, default: no) tsa_name = yes # Must the TSA name be included in the reply? # (optional, default: no) ess_cert_id_chain = no # Must the ESS cert id chain be included? # (optional, default: no)
Glossary
Before we continue a little tiny glossary of the acronyms used in the file:
- CA: stands for Certificate Authority
- CRL: stands for Certificate Revocation Lists
- CSR: stands for Certificate Signing Request
- MD: stands for Message Digest
- TSA: stands for Time Stamping Authority
Certificates repository
Next, create the directories and (for now empty) files to store our keys and certificates:
# cd /var/openssl
# mkdir -p yourCA/CA
# mkdir -p yourCA/newcerts
# mkdir -p yourCA/certs/keys
# mkdir -p yourCA/certs/requests
# mkdir -p yourCA/certs/certificates
# cd yourCA
# touch index.txt
# echo 01 > serial
CA certificate
Now you can create your Certificate Authority certificate and sign it. But first, we need to create a private key with the following command:
# /usr/local/bin/openssl genrsa -out yourCA/CA/yourCA.key 2048
Secondly, create a CSR by running:
# /usr/local/bin/openssl req -new -key ./yourCA/CA/yourCA.key -out yourCA/CA/yourCA.csr
Follow the instructions on screen, paying attention to fill the correct information. Finally, self-sign your certificate:
# /usr/local/bin/openssl x509 -req -days 365 \
> -in yourCA/CA/yourCA.csr -out yourCA/CA/yourCA.crt \
> -signkey yourCA/CA/yourCA.key
And this is it: now you can start signing your client and or web certificates
Client certificates
The process is pretty similar as the former one. But we are using our CA certificate to sign the client certificate. And, ideally, the client will generate his own private key and the CSR.
Anyway, we are just testing stuff, so I’m doing every step and then distributing the generated certificates to my user. The following commands can be runned everywhere, but just to keep some order I’m using the previously created folders (under /var/openssl/yourCA/certs). Our user, John Doe, need a private key first:
# cd /var/openssl/yourCA/certs
# /usr/local/bin/openssl genrsa -des3 -out keys/johndoe.key 2048
Don’t forget the passprhase as will be asked several times; next create the certificate signing request:
# /usr/local/bin/openssl req -new -key keys/johndoe.key -out requests/johndoe.csr
Next, sign the certificate with this command:
# /usr/local/bin/openssl ca -in requests/johndoe.csr -cert ../CA/yourCA.crt -keyfile ../CA/yourCA.key -out certificates/johndoe.crt
Finally, export the certificate to the PKCS12 format, you’ll be asked for the passphrase of the PK:
# /usr/local/bin/openssl pkcs12 -export -clcerts -in certificates/johndoe.crt -inkey keys/johndoe.key -out certificates/johndoe.p12
Installing the certificate
Now you can emit your own certificates your user needs to install them in order to use it. You need to deliver two files: yourCA.crt and the personal johndoe.p12.
To install it on windows use the Certificate Manager Tool. I’m not uploading several screenshots because, as my windows is in spanish, I wouldn’t find it very useful. Click on start menu an run “certmgr.msc”, the following screen will popup:
Right-click on the folder Root Certification Authority and choose “Import”. Start with yourCA.crt and choose the store Root Certification Authority, follow the wizard.
Now right-click on the Personal folder and repeat the wizard with the johndoe.p12 file. You will be asked for the passprhase. When the wizard completes you can see your installed valid certificate and the details:
Remember, this is for learning purposes only. But this is also a matter of trust. If your organization is small enough and there is trust, you should be able to work with this DIY certificates.