The most difficult aspect of PKI implementation is certificate management. Before certificate management can begin, it’s important to understand key fundamentals such as the types of certificates, use cases, and the overall creation process of the certificate requests. Each one of these has a specific use case and must be created in a specific manner.
There are three main types of digital certificates:
- TLS (Server side): Identifies and validates a website or service and secures a communication channel
- Client Certificates: Provides authentication, data encryption, and email signature
- Code Signing Certificates: Signs compiled binary code to validate the authenticity
To create a server TLS certificate:
openssl req-new -newkey rsa:2048 -keyout $HOSTNAME.key -sha256 -nodes -out $HOSTNAME.csr -subj "/CN=$FQDN" -openssl.cnf EXAMPLE: openssl req-new -newkey rsa:2048 -keyout test.key -sha256 -nodes -out test.csr -subj "/CN=test.domain.net" -openssl.cnf |
##Required ##About the system for the request. Ensure the CN = FQDN ##Extensions to add to a certificate request for how it will be used ##The other names your server may be connected to as |
The previous command will result in a CSR named test.csr and test.key.
Check the CSR that expected values were set:
openssl req -in test.csr -noout -text |
Certificate Request:
Data:
Version: 0 (0x0)
Subject: CN=test.domain.net
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Attributes:
Requested Extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage: critical
Digital Signature, Non Repudiation, Key Encipherment
X509v3 Extended Key Usage: critical
TLS Web Server Authentication
X509v3 Subject Alternative Name:
DNS:test, DNS:test.domain, DNS:testing.domain.net, DNS:192.168.1.122
To create a client certificate:
openssl req -new -newkey rsa:2048 -keyout testuser.key -sha256 -nodes -out testuser.csr -subj "/CN=testuser" -config clientopenssl.cnf |
Example of a client configuration clientopenssl.cnf:
[ req ] ##About the user for the request ##Extensions to add to a certificate request for how it will be used |
Resulting certificate request testuser.csr:
openssl req -in testuser.csr -noout -text |
Certificate Request:
Data:
Version: 0 (0x0)
Subject: CN=test
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit
Attributes:
Requested Extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage: critical
Digital Signature, Non Repudiation, Key Encipherment
X509v3 Extended Key Usage: critical
TLS Web Client Authentication
To create a code signing certificate:
openssl req -new -newkey rsa:2048 -keyout testsign.key -sha256 -nodes -out testsign.csr -subj "/CN=testsign" -config codesign.cnf |
Example of a code signing openssl configuration codesign.cnf:
[ req ] [ codesign_dn ] [ codesign_reqext ] |
Resulting certificate request testsign.csr:
openssl req -in testsign.csr -noout -text |
Certificate Request:
Data:
Version: 0 (0x0)
Subject: CN=test
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Attributes:
Requested Extensions:
X509v3 Key Usage: critical
Digital Signature
X509v3 Extended Key Usage: critical
Code Signing
Ensure certificate validity
Each one of these certificate generation techniques have very specific use cases and one certificate request should not be used for all three use cases even though it is technically possible. Mixing certificate requests methods with the wrong use case is a very dangerous thing to do and the three functions should always be treated separately.
Let’s talk about the top items you need to verify before you begin. Most issues occur in the creation of the certificate.
First and foremost, for any webserver certificate, there are three things which need to be absolutely correct. If any fail, your certificate will not be valid.
Fully Qualified Domain Name (FQDN) and the Subject Alternative Name (SAN)
DNS Match for your FQDN
Extended Usage set to serverAuth
Before you send the certificate request to the CA for signature, you can check the CSR for these items by using the below commands. Please check the attributes to ensure they match the example above.
openssl req -in test.csr -noout -text |
Once the cert is returned to you signed by the CA you can create a PKSC12 key store:
openssl pkcs7 -in test.p7b -print_certs -out test.pem openssl pkcs12 -export -in test.pem -inkey test.key -out test.p12 -name test.domain.net |
Check the created PKCS12 key store:
openssl pkcs12 -info -in test.p12 |
If needed you can create a Java key store directly from the created PKCS12 keystore:
keytool -importkeystore -srckeystore test.p12 -srcstoretype PKCS12 -destkeystore test.jks -deststoretype JKS -srcalias test.domain.net -destalias test.domain.net |
Check the Java Keystore:
keytool -list -v -keystore test.jks |
Uppercase vs. lowercase: Nix servers case can cause issues and should match the FQDN in the /etc/hosts file. In the case of Windows, there is not much difference. You can check the server certificate after it is signed and returned:
openssl x509 -in test.pem -noout -text |
You should see something like this:
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 14 (0xe)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=I-CA
Validity
Not Before: Nov 29 14:20:54 2018 GMT
Not After : Nov 29 14:20:54 2020 GMT
Subject: CN=test.domain.net
Subject Public Key Info:
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 15 (0xA)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=I-CA
Validity
Not Before: Nov 29 14:25:51 2018 GMT
Not After : Nov 29 14:25:51 2020 GMT
Subject: CN=TEST.DOMAIN.NET
Subject Public Key Info:
In Active Directory (AD), users have to match the SAM-Account-Name, and in all other V3 compliant LDAP instances, the UID must match and the case should match to be valid. . Once the user certificate is returned, it can be checked.
openssl x509 -in testuser.pem -noout -text |
You should see something like this:
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 14 (0xe)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=I-CA
Validity
Not Before: Nov 29 14:20:54 2018 GMT
Not After : Nov 29 14:20:54 2020 GMT
Subject: O=DOMAIN.NET, CN=testuser
Subject Public Key Info:
Code signing certificates are the least common to create and by far are the most expensive to generate if you are using an external CA and will be selling your software. If the intent is to sell your developed software or offer it as a compiled program, using a code signing certificate to sign your software helps both your internal and external clients ensure its authenticity. A code signing certificate’s only function should be for code signing. It needs to be well-protected, much like a server which is not connected to a network. In addition, the password for the key needs to be strong to minimize the ability to crack the keys.
Openssl can be used to validate your certificate before you send it off to the CA for signature:
openssl x509 -in testsign.pem -noout -text |
Understand certificates to prepare for management
To wrap things up, understanding certificates and the use case for each one is the first step in managing them. External certificate authorities can cost thousands of dollars per certificate and if the certificates are for internal use only, then you should use a product like Red Hat Certificate Management to manage those functions and generate your own certificates.
One last point that I would like to make is when you are generating your certificates, they should all be created on the same server regardless of the system. You should protect the keys and keep them in a consolidated location to be able to maintain and reissue certificates as needed.