PKI 101

Public Key Infrastructure, aka PKI, is a set of roles, procedures and policies used to manage digital certificates and public key encryption. The end goal is to provide a secure method of exchaning information between parties.

1. Public Key Cryptography

1.1 Symmetric Encryption

With symmetric encryption, the same key is used for both encryption and decryption. So if A wants to send B the raw message M, it will use the key K to generate the encrypted message E. When B receives the encrypted message E, it will use the same key K to decrypt it and it will get the raw message M.

As you can see, both A and B must have a shared key provided to both of them ahead of time. Hence the term usually used for this aproach: using a pre-shared key (or secret). It’s biggest flaw is that secure methods to share the key are hard to find or implement.

1.2 Asymmetric Encryption (PKC)

With asymmetric encryption, aka Public Key Cryptography (PKC), there is one key used in the encryption process and another key used in the decryption process. Therefore, we have a key-pair.

The two keys in the pair are called private-key and public-key. As the name suggests, a public-key can be shared with anyone but the private-key should only be known to the entitiy it belongs to.

The keys in the key-pair must have certain characteristics in order to be viable. This is done via a mathematical relationship between the private-key and the public-key. The most important characteristic of this relationship is that messages encrypted with the public-key can only be decrypted with the private-key. It doesn’t work the other way around and it is computationaly unfeasable to deduce the private-key from the public-key or other data exchanged between the parties. The method used to exchange the key information between parties is known as Diffie-Hellman and RSA (Rivest-Shamir-Adleman) is an implementation of this method.

The DH method is mostly used to secretly agree on a shared key between the parties envolved in a data exchange. Once the shared key is established, it is further used to encrypt the messages exchanged between parties because symmetric encryption is a much simpler process and through this method, it’s biggest flaw – sharing the secret – is addressed

1.2.1 Generating a Private Key using openssl

To create a Private Key using OpenSSL, use this command:

openssl genrsa [NUMBITS] [-out OUTPUT_FILE] [-passout PASSOUT] [-des|des3|-aes128|aes192|aes256|...]
NUMBITS = Size of the key. Defaults to 2048.
-out OUTPUT_FILE = Saves the key to OUTPUT_FILE
-passout PASSOUT = The key in the OUTPUT_FILE can only be read if the PASSPHRASE is porovided.
If passout is not provided then the user will be asked to enter it. Some common methods to provide the PASSPHRASE are:
pass:PASSPHRASE - provides the passphrase as argument
file:PASSFILE - provides a file that contains the passphrase
stdin - asks the user to provide the passphrase
-des|des3|aes128|aes192|aes256|... = Select the method for file encryption.

The passphrase is actually used for a symmetric encryption that adds a layer of protection for the private key.

Instead of openssl genrsa ...command you should use the newer and more versatile openssl genpkey -algorithm RSA ...command. It is meant to suport multiple key types, not just RSA but otherwise follows the same idea while bringin several improvements and more secure defaults.

When looking at an encrypted private key you should see that it includes information about the type of encryption that is used. That information is not present if the key is not protected.

Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,1C65746D94033797A4EE53B3FCC8FAF6

To read the key from an encrypted file you can use:

openssl rsa -in INPUT_FILE [-passin PASSIN] [-out OUTFILE] [-passout PASSOUT]
-passin PASSIN = provide the passphrases needed to read the private key. Follows the same format as PASSOUT
-out OUTFILE = when used it outputs the private key to a file. When it is not used the output will be to screen (stdout)
-passout PASSOUT = privide the passphtrase for the output file.

1.2.2 Generating a Public Key using openssl

The same command can be used to generate a public key based on the private key:

openssl rsa -in INPUT_FILE [-passin PASSIN] -pubout [-out OUTFILE]
-passin PASSIN = provide the passphrases needed to read the private key. Follows the same format as PASSOUT
-out OUTFILE = when used it outputs the private key to a file. When it is not used the output will be to screen (stdout)
-pubout = will output the Public Key associated with the input private key

2. Digital Certificates

One of the most important things when it comes to crytpography is authentication which is the process of verifying that an entity really is who it claims to be. In modern cryptography this is usually done through a digital certificate.

A digital certificate binds an entity’s identity with a public key. The binding is performed by a Certificate Authority (CA) through the process of signing.

2.1 Generate a key pair

The process of getting the certificate signed starts with an entity generating a key-pair.

2.2 Create a Certificate Signing Request (CSR)

The next step for the entitiy is to create a Certificate Signing Request (CSR) which will contain the public-key, the identity information, the Distinguished Name (DN) for which it requests the certificate and a section which is generated using the private-key. That is to say the private-key is not part of the CSR but it is used to sign the CSR in order to attest that the request comes from the owner of the public-key.

2.2.1 Creating a CSR using openssl

openssl req -new -key PRIVATE_KEY [-passin PASSIN] -out OUTPUT_FILE
-new = Creates a new CSR
-key PRIVATE_KEY = provides the PRIVATE_KEY needed to generate the Public Key and to sign the request
-passin PASSIN = provides the PASSPHRASE for the PRIVATE_KEY
-out OUTPUT_FILE = saves the request to the provided OUTPUT_FILE

If you don’t have an existing Private Key you can generate the key and the CSR in the same stept using:

openssl req -newkey rsa:NUMBITS -keyout PRIVATE_KEY_FILE -out CSR_FILE [-subj SUBJECT]
-newkey rsa:NUMBITS = will create a RSA key of NUMBITS size.
-keyout PRIVATE_KEY_FILE = will store the generated private key in this file
-out CSR_FILE = will store the genertated CSR in this file

Additional identity information will be asked from the user. These make up the DN(Distinguished Name). You can suppress these questsion by providing the reqiured information using the -subj argument.

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) []:NY
Locality Name (eg, city) []:NYC
Organization Name (eg, company) []:
Organizational Unit Name (eg, section) []:
Common Name (eg, fully qualified host name) []
Email Address []:[email protected]
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:challenge

The Common Name (FQDN) is important because this value will have to match your web server address when you you plan to use the certificate for this.

The challenge information requested at the end of the CSR is a password that will be shared between you and the CA.

To read the contents of a CSR you can use:

openssl req -in INPUT_CSR -text
Certificate Request:
Version: 0 (0x0)
Subject: C=US, ST=NY, L=NYC,[email protected]
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Exponent: 65537 (0x10001)
challengePassword :unable to print attribute
Signature Algorithm: sha256WithRSAEncryption

2.2.2 Signing the CSR at the CA

The CSR could go through a Registration Authority (RA) that verifies the identity of the entitiy against the provided CSR before reaching the Certificate Authority (CA) for signing. Most of the times, RA and CA are the same so it all looks like a single step.

To sign a CSR (and get a self-signed certificate) you can use the following openssl command:

openssl req -x509 -in CSR_FILE -key CA_RSA  -days DAYS -out OUT_CRT
-x509 = Request an x509 certificate
-in CSR_FILE = input of the CSR request
-key CA_RSA = private key of the signing entity.
-days DAYS = how many days should the certificate be available
-out OUT_CRT = certificate output file

After it is signed, the certificate is exported to the requester. The standard for these certificates is registered as X.509 but there are different formats for the certificate (.pem, .p12, .cer, .crt and others). The p12 format allows adding an additional passphrase to the certificate so it is not readable without knowing the passphrase.

To decode the information of a crt file you can use:

openssl x509 -text -in CRT_FILE
Version: 1 (0x0)
Serial Number: 18430850791973880580 (0xffc78924fbd48304)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=NY, L=NYC,[email protected]
Not Before: Nov 19 20:05:57 2019 GMT
Not After : Nov 18 20:05:57 2020 GMT
Subject: C=US, ST=NY, L=NYC,[email protected]
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Exponent: 65537 (0x10001)
Signature Algorithm: sha256WithRSAEncryption

2.3 Chain of Trust

A certificate chain is a list of certificates that have the following characteristics:

  • The issuer of each certificate matches the subject of the next certificate in the list.
  • The private-key used to sign each certificate can be verified using the public-key of the next certificate in the list
  • The last certificate in the list is trusted through other methods (manually set to trust, embedded in the system, etc)

By using this chain of trust, the certificate provided by an entitiy is verified by another entity and the chain goes from the certificate under verification, through intermediate certificates, up to the CA’s root certificate.

In some simple scenarios you can provide your own certificate by performing the signing process yourself. In this case the certificate is called “self-signed” but others may not have a high level of trust in this kind of certificate.

Web browsers usually include intermediate certificates provided by well-known CAs and set to trust in order to enable the verification process to take advantage of the chain up to the well-known CAs without passing their root certificates to the public.

A useful command to check the certificate of a website is:

openssl s_client -showcerts -connect

Leave a Reply

Your email address will not be published. Required fields are marked *