Create Private Certificate Authority on Linux
April 16, 2013
This tutorial will show you how to create your own private CA or Certificate Authority. This will give you the opportunity to sign your own certificates without having to pay someone else. However, since your private CA will not be trusted by others it may prompt warnings when others use it. You will need to add your root certificate to the machines you want to trust your CA.
I had written a similar article in 2008 (Create a Certificate Authority and Certificates with OpenSSL) but this tutorial supersedes the instructions for creating CA in the older one.
I wrote this tutorial using Fedora 18. The only prerequisite I needed was OpenSSL.
su -c 'yum install openssl'
Create Directory Structure
mkdir private certs newcerts conf export csr
echo '01' > serial
We will run all commands by default in the /home/cg/myca directory, unless stated otherwise.
This file would serve as the default config file for the CA. It should look something like the following:
[ ca ] default_ca = CA_default [ CA_default ] dir = /home/cg/myca/ certs = $dir/certs crl_dir = $dir/crl database = $dir/index.txt new_certs_dir = $dir/newcerts certificate = $dir/certs/cacert.pem serial = $dir/serial #crl = $dir/crl.pem private_key = $dir/private/cakey.pem #RANDFILE = $dir/private/.rand x509_extensions = usr_cert #crl_extensions = crl_ext default_days = 3650 #default_startdate = YYMMDDHHMMSSZ #default_enddate = YYMMDDHHMMSSZ #default_crl_days= 30 #default_crl_hours = 24 default_md = sha1 preserve = no #msie_hack policy = policy_match [ policy_match ] countryName = match stateOrProvinceName = match localityName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional [ req ] default_bits = 4096 # Size of keys default_keyfile = key.pem # name of generated keys distinguished_name = req_distinguished_name attributes = req_attributes x509_extensions = v3_ca #input_password #output_password string_mask = nombstr # permitted characters req_extensions = v3_req [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = US countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = New York localityName = Locality Name (city, district) localityName_default = New York organizationName = Organization Name (company) organizationName_default = Code Ghar organizationalUnitName = Organizational Unit Name (department, division) organizationalUnitName_default = IT commonName = Common Name (hostname, FQDN, IP, or your name) commonName_max = 64 commonName_default = CGIT emailAddress = Email Address emailAddress_max = 40 emailAddress_default = email@example.com [ req_attributes ] #challengePassword = A challenege password #challengePassword_min = 4 #challengePassword_max = 20 #unstructuredName = An optional company name [ usr_cert ] basicConstraints= CA:FALSE subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer:always #nsComment = ''OpenSSL Generated Certificate'' #nsCertType = client, email, objsign for ''everything including object signing'' subjectAltName=email:copy issuerAltName=issuer:copy #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem #nsBaseUrl = #nsRenewalUrl = #nsCaPolicyUrl = #nsSslServerName = [ v3_req ] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment [ v3_ca ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always basicConstraints = CA:TRUE #keyUsage = cRLSign, keyCertSign #nsCertType = sslCA, emailCA #subjectAltName=email:copy #issuerAltName=issuer:copy #obj=DER:02:03 [ crl_ext ] #issuerAltName=issuer:copy authorityKeyIdentifier=keyid:always,issuer:always
Thanks to http://wwwneu.secit.at/web/documentation/openssl/openssl_cnf.html for helping with this file.
Generate Root Certificate
You can use the config file (caconfig.cnf) we created in the previous step to answer a lot of the questions asked during certificate generation. Just run the following command and answer the questions. Most questions will have the default values provided in caconfig.cnf.
openssl req -new -x509 -days 3650 -config conf/caconfig.cnf -keyform PEM -keyout private/key.ca.cg.pem -outform PEM -out certs/crt.ca.cg.pem
Although we specified the default number of days in caconfig.cnf file, we still have to specify the
days flag when using the x509 flag. If we don’t the certificate is created with a default value of 30 days. Thanks to Re: default_days problem and OpenSSL req(1).
If you want to provide your own custom values you may run the following command instead.
openssl req -new -x509 -days 3650 -newkey rsa:4096 -extensions v3_ca -keyform PEM -keyout private/key.ca.cg.pem -outform PEM -out certs/crt.ca.cg.pem
You will be asked for a passphrase. Make sure you use a secure passphrase and don’t forget it. You will also be asked other relevant questions. Following is an example output of the process.
Generating a 4096 bit RSA private key ..............................................................................++ ...........................................................................................................................................................................................................................................++ writing new private key to 'private/key.ca.cg.pem' Enter PEM pass phrase: Verifying - Enter PEM pass phrase: ----- 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) [US]: State or Province Name (full name) [New York]: Locality Name (city, district) [New York]: Organization Name (company) [Code Ghar]: Organizational Unit Name (department, division) [IT]: Common Name (hostname, FQDN, IP, or your name) [CGIT]: Email Address [firstname.lastname@example.org]:
Two files, key.ca.cg.pem and crt.ca.cg.pem, will be created in $dir/private and $dir/certs directories respectively. Make sure you keep these files in a secure place and make their backups.
crt.ca.cg.pem is your root certificate and will be used to sign all the other certificates.
Verify Root Certificate
You should verify that the certificate was created properly with accurate information.
openssl x509 -in certs/crt.ca.cg.pem -inform pem -noout -text
Export Root Certificate
Since this newly created CA and its root certificate are not recognized and trusted by any computer, you need to import the root certificate on all other computers. By default an OS will have a list of trusted CAs and you need to import your CA to that list. The process varies for different OSes.
The root certificate we created is in PEM encoded format. For Windows we need it to be in DER encoded format. A great resource on the differences between the two is DER vs. CRT vs. CER vs. PEM Certificates and How To Convert Them.
openssl x509 -in certs/crt.ca.cg.pem -outform der -out export/ca.cg.crt
Verify the certificate was created successfully.
openssl x509 -in export/ca.cg.crt -inform der -noout -text
Once you have the exported file, copy it to your Windows machine. You can follow the instructions provided by How To Import a Trusted Root Certification Authority In Windows to import the certificate to the Trusted Root Certification Authorities store on Local Computer.
You can also export the certificate to PKCS12 format. Thanks to Importing a User Certificate to the Windows Certificate Store for this information.
openssl pkcs12 -export -out export/ca.cg.p12 -in certs/crt.ca.cg.pem -inkey private/key.ca.cg.pem
You will be asked to provide the passphrase you used to create the root certificate. You will also be asked for a new “Export Password”.
Copy the .p12 file to Windows and double-click it. A wizard will open and guide you to install it.
The process to create a CA is very simple. Next I will write about signing a certificate request.