# Key management

We now discuss how keys are managed, stored and checked by parties and KDC servers.

### Symmetric key management

We have seen that practical authentication protocols based on symmetric keys require the presence of a centralised trusted party that shares one long-term key with each possible user. It is important to have a way to securely deal with these keys so that an attack to the KDC system would not necessarily compromise the keys of all users.

An interesting solution to this problem is provided by symmetric key certificates. The trusted party possesses a master key $K_M$ that it only knows. When a new user $U$ is registered, the respective long-term key $k_U$ is generated and is encrypted under the master key together with the identifier and additional information such as the key lifetime, type, etc. For example $SCert_U = E_{K_M}(U,k_U,L)$ certifies that user $U$ has key $k_U$ with lifetime $L$.

These certificates can be distributed to users together with their keys and users can freely distribute their certificates to other users, since the encryption under the master key protects the confidentiality of the enclosed keys. The trusted party can completely forget about the keys and ask for certificates when needed. As an example, let us consider again the Kerberos protocol. The first message $A,B,N_A$ representing a request from A to B with nonce $N_A$, would be replaced by $SCert_A,SCert_B,N_A$. The KDC decrypts the two certificates and obtains the keys for Alice and Bob together with their identifiers, that will be enclosed in next messages for Alice: $E_{K_A}(k_s,B,N_A,{L}),E_{K_B}(k_s,A,{L})$. After these messages have been generated, $K_A,K_B$ can be deleted.

### Asymmetric key management

The idea of certificates is even more important for protocols based on asymmetric keys. In this case, in fact, it is crucial that key management is completely decentralised since we do not want any on-line centralised servers available at each protocol execution.

First notice that the relevant property here is authenticity of public keys. If Alice and Bob want to communicate they need a way to check that public key is the one truly associated with the opposite party. Suppose Alice wants to send Bob a secret message M. It is insecure for Bob to simply send his public key to Alice:

$\begin{array}{l} B \rightarrow A: PK_B \\ A\rightarrow B: E_{PK_B}(M) \end{array}$

In fact, an attacker can replace $PK_B$ with his own key:

$\begin{array}{cccl} E(B) & \rightarrow & A &: PK_E \\ A & \rightarrow & E(B) & : E_{PK_E}(M) \end{array}$

The attacker can then decrypt the secret message encrypted under his public key.

We need a mechanism that allows Alice to check that the received key is the one belonging to Bob. Public key certificates contains the same informations as the symmetric key ones but, instead of being encrypted under a symmetric master key, they are signed by a Certification Authority (CA), a trusted entity that certifies the authenticity of user’s public keys. For example $Cert_B = B, PK_B, L, sign_{CA}(B, PK_B, L)$. If Alice knows the public key of the CA and Bob sends this certificate, then Alice can check the validity of the key and its association with Bob (B). The protocol becomes:

$\begin{array}{l} B \rightarrow A: Cert_B \\ A\rightarrow B: E_{PK_B}(M) \end{array}$

The attacker cannot change the public key as he is not able to forge a signature from the CA.

#### Generating real certificates with openssl

We now show all the steps required to generate a ‘root’ CA certificate, i.e., the self-signed certificate holding the CA public key that Alice and Bob use to verify their respective public keys. OpenSSL allows for executing all of these operation via command-line. The root CA key and certificate can be generated as follows:

We now have a self signed certificate cacert.pem (option -x509) and a new private key cakey.pem, protected via a pass phrase. If we want to use these as if they were from a CA, we need to save them in a directory structure as follows (index.txt and serial are needed for tracking certificate generation):

Alice and Bob can now send to the CA their certificate signing requests (CSRs) that the CA signs, producing two certificates that are given to the two users. CSRs are generated by Alice and Bob as follows:

We now have a new key, let’s say for Alice, in Alice_key.pem and a CSR in Alice_req.pem. The CSR is what we send to the CA to be signed, producing the final certificate for Alice public key. In particular the CSR contains Alice public key but NOT the private key, so that it can be safely sent in the clear. Suppose the CA has received the CSR. It can now produce the certificate as follows:

We have produced the certificate for Alice in file Alice_crt.pem, signed by the CA. Suppose now that Bob wants to communicate with Alice and he possesses the CA root certificate cacert.pem. He can check Alice certificate as follows:

This confirms that Alice certificate is correctly signed by the CA represented by cacert.pem. The public key can be extracted from the certificate as follows:

And of course Bob can query about the subject and email:

Now Bob can use this public key knowing that it belongs to Alice, as far as he trusts the DAIS CA identified by the cacert.pem certificate.

The Transport Layer Security (SSL/TLS) protocol. When we connect to a web site using https, the SSL/TLS protocol establishes a secure, encrypted session. The association of the identity and the public key of the web server is checked using certificates and the asymmetric key of the web server is used to establish a new session key. Any subsequent communication is encrypted under the session key. To allow for certificate check, browsers include a number of built in CA root certificates. For a web site it is enough to require a web site certificate from one of these official CA’s.

Sometimes, we connect to sites that have generated their own certificates. In these cases the browsers warn that something is wrong and that the certificate cannot be checked. Accepting the certificate is at our own risk: it could be the case that there is a man-in-the-middle attacker setting up a fake site using a self signed certificate, and intercepting/modifying all subsequent messages (sniffing our credentials, modifying the bank transfers we perform, etc.). If we store permanently the certificate, next connections will be guaranteed to be with the same server as the previous one, but this does not prevent we are under a man-in-the-middle attack right now, of course.

#### Certificate chains

Having just root CA’s signing any certificate in the world does not scale well. It is useful in practice to have different levels of certifications (maybe associated with countries, states, cities, etc.) so that the end user can go the ‘local’ CA. To deal with this hierarchical organisation of CA’s we need to be able to check certificate chains: The root CA certifies the next CA in the hierarchy and so on all the way to the end user. Once we provide the whole chain, it is enough to trust the root public key in order to check all the certificates in the path to the end user.

Above we illustrate two end users Carol and Dave certified by two different CAs under the same root CA. If Carol wants to communicate with Dave, she needs to send Dave the certificate chain from the root CA to herself: $\mathrm{CA}_1$ certificate signed by $\mathrm{CA}_{root}$, $\mathrm{CA}_3$ certificate signed by $\mathrm{CA}_1$ and Carol’s certificate signed by $\mathrm{CA}_3$.

To give a practical example with openssl, we can think of Alice as an intermediate CA certifying Bob. Above, we have already generated a certificate for Alice signed by our DAIS CA. In a similar way we can generate a certificate for Bob signed by Alice. Since Alice certificate is signed by the DAIS CA, if Eric wants to check Bob’s certificate he would need the whole path from the CA to Bob which is CA->Alice->Bob.

This is Bob’s certificate signed by Alice (we leave as an exercise the generation of Bob’s certificate, notice that openssl uses default paths to look for CA certificates and keys. These paths can be changed in the configuration file):

We can check the chain as follows:

If we omit Alice certificate verification fails, as expected:

Chains can be arbitrarily long.

#### Further extensions

The basic hierarchal tree organisation illustrated above can be extended to multi-trees, where many root CAs are present (as typically happens in browsers): if any users know many root CAs it is enough a chain from one of the roots to a leaf to certify the corresponding user. To avoid storing all the root certificates, root CAs might certify each other so that any root CA is ‘reachable’ by any other.

Interestingly, there are solutions where no centralised authorities are required. In Pretty Good Privacy (PGP) it is proposed a web-of-trust: any user can trust other users. The level of trust might be such that if Alice trusts Bob, any other user certified by Bob is trusted by Alice. In a sense, each user can ‘elect’ other users as CA’s that can be trusted when signing certificates for other users. This can be depicted as a general graph with no roots: a path in the graph represents a chain of certificates from oner user to the other. If we trust the starting user, we can successfully verify the identity and public key of the final user in the path.