Getting Anyway from PKI and Properly Defining a Trust Infrastructure

If there’s one thing that the recent Facebook hack showed, it is that a breach of the trust infrastructure can expose massive holes in the…

Getting Away from PKI and Properly Defining a Trust Infrastructure

If there’s one thing that the recent Facebook hack showed, it is that a breach of a trust infrastructure can expose massive holes in any security infrastructure. It, possibly, has the greatest potential amount of damage and is often expensive to clean up. Companies thus need to think deeply about how the setup their trust infrastructure, and make sure their encryption keys are properly secured and managed, and that the access to these keys, and the rights that they bring, are also clearly defined.

One of the most expensive things for a company to resolve is a trust infrastructure breach, and where encryption keys are compromised. This might be a single key to access the SSH session for a Cloud infrastructure, or the breach of the private key which is used to secure the Web infrastructure. Unfortunately, many companies still use PKI (Public Key Infrastructure) for their infrastructure, and where the usage of digital certificates — and their static keys — can cause many problems.

So what is the solution? Well, a Key Distribution Centre (KDC) is one of the best to overcome the nightmare of dealing with digital certificates, especially in a world of IoT (and where you might have billions of devices). Within this, we define a highly secure trust infrastructure, and which will protect the encryption keys that we use:

We need a trusted person — Trent. In this case, let’s say that Trent to create a safe deposit box, and for Alice to put some money in, and for Bob to withdraw it. If Alice sends the key in the post, she will not know if Bob has actually received the right key. So Bob and Alice each create a key for a padlock and then pass the key to Trent. He then gets a request from Alice to create a new key, and he takes Bob’s key and takes a picture of Alice, and adds the date on it. He then puts this in a box, and the new secret key. He then locks this box and puts Bob’s padlock on it. He then gets another box, and puts the box for Bob into their box, along with the new key. He then locks the box, and adds Alice’s padlock, and send it to her. She opens it and takes out the key. She then puts the money in the safe deposit box and sends the other box to Bob. He opens and checks Alice’s photograph, Trent’s signature, and date that the photography was taken. He takes the key out, and goes and gets him money:

So let’s look at a simple example of the KDC. Within the KDC, Bob and Alice will have a long-term key (KEK — Key Encryption Key) and which is generated for them (or where they register their own long-term key). We can change this key at any time, or have a regular refresh. If Alice wants to communicate with Bob, she sends a request with her ID, and Bob’s ID. The KDC then creates a random key and then encrypts it with Alice’s KEK, and sends it to her. It will also encrypt the session key with Bob’s KEK, and send that to him. Bob and Alice then decrypt the received value with their long-term keys, and they will have the same session key:

Some sample code used is given next. In this case we are just using a 128-bit key, and using MD5 to take a hash of the 128-bit random number [here]:

import hashlib
import sys
import binascii
import Padding
import random

from Crypto.Cipher import AES
from Crypto import Random

msg="test"

def encrypt(word,key, mode):
plaintext=pad(word)
encobj = AES.new(key,mode)
return(encobj.encrypt(plaintext))

def decrypt(ciphertext,key, mode):
encobj = AES.new(key,mode)
rtn = encobj.decrypt(ciphertext)
return(rtn)

def pad(s):
return s
extra = len(s) % 16
if extra > 0:
s = s + (' ' * (16 - extra))
return s


rnd = random.randint(1,2**128)

keyA= hashlib.md5(str(rnd)).digest()

rnd = random.randint(1,2**128)

keyB= hashlib.md5(str(rnd)).digest()

print 'Long-term Key Alice=',binascii.hexlify(keyA)
print 'Long-term Key Bob=',binascii.hexlify(keyB)

rnd = random.randint(1,2**128)
keySession= hashlib.md5(str(rnd)).hexdigest()

ya = encrypt(keySession,keyA,AES.MODE_ECB)
yb = encrypt(keySession,keyB,AES.MODE_ECB)

print "Encrypted key sent to Alice:",binascii.hexlify(ya)
print "Encrypted key sent to Bob:",binascii.hexlify(yb)

decipherA = decrypt(ya,keyA,AES.MODE_ECB)
decipherB = decrypt(yb,keyB,AES.MODE_ECB)

print "Session key:",decipherA
print "Session key:",decipherB

A sample run gives [here]:

Long-term Key Alice= 9997205ef32f910d094b11b5f02ffe23
Long-term Key Bob= c2d0b8ac3567ac1f7305d223cecf3cbe
Encrypted key sent to Alice: 2c4ebf8e8748cb11065bb3cba7869c1af9d877c08805b2232ad4c7d8b2f987d5
Encrypted key sent to Bob: 8d9d34a0cf2385a328643e83c11f5523b9d241db50d2e534c563dbbac9bb08ba
Session key: 0ff7556d5a49f4f84f1b7e7c61c7c869
Session key: 0ff7556d5a49f4f84f1b7e7c61c7c869

We can see that Bob and Alice end up with the same 128-bit encryption key. They can then use that to encrypt their messages. The session key, in the best case, should change for every session but could stay valid for a given amount of time.

We can enhance the method by sending back Bob’s encrypted session key, and for Alice to pass this onto him. Bob will know if the key is correct, as Alice will not be able to generate the right session key that she encrypts with (and that he can decrypt):

Kerberos

So we now have three parties involved: Bob, Alice and Trent (the KDC). One of the most developed KDC infrastructures uses the Kerberos protocol.

Kerberos (or Cerberus) was defined in Greek and Roman mythology as, typically, a three-headed dog. It is often known as the hell-hound that guards the gates of the Underworld, in order to stop those who have crossed the river Styx from escaping. As we’ll find both the description of the three-headed beast fits the three-way communication, and also that the protocol is a bit of a beast.

One of the best protocols for implementing this trust infrastructure is Kerberos. It is fairly complex in its implementation, but it supports both the security of the transmitted data between Bob and Alice and also proves the identity of both Bob and Alice. So with the Kerberos protocol, Alice and Bob first deposit their secret keys and will define their unique identifies (such as their email addresses). Trent will then be trusted to store these keys. What we need now is to generate a session key between Bob and Alice that they can use, and also to be able for Trent to prove Alice’s identity to Bob, and also Bobs identity to Alice. An example is here:

Kerberos encryption

Step 1: First Alice sends her identity, and Bob’s to Trent, who will then find the keys where relate to them.

Step 2: Next Trent creates a random key to be used for the session key, and create a Timestamp (T), a Lifetime (L), which define the starting time for the trust relationship, and how long it will be valid for. He will then create two parts to send back to Alice:

EA(T,L,K,B) and EB(T,L,K,A)

where is the first part is encrypted with Alice’s secret key, and the other part is encrypted with Bob’s secret key.

Step 3: Next Alice will decrypt the first part, and can thus determine T (the timestamp), L (the lifetime), K (the session key) and B (Bob’s Identity). Alice now knows the session key (K), and now uses it to encrypt the Timestamp (T) and Alice’s Identity (A) to Bob, along with the second part of the message from Trent [EB(T,L,K,A)]:

EK(T,A) and EB(T,L,K,A)

Step 4: Bob will then decrypt the second part, and determines the session key (K), which can be used to decrypt the first part. He will then check Alice’s identity is the same as the one that Trent sent.

Step 5: Bob takes the time stamp and add one onto it, and sends back to Alice:

EK(T+1)

Step 6: Alice then decrypts with the session key, and checks the timestamp. If it checks with the expected value, then Bob has proven his identity. Bob and Alice and now communicate using the session key, and be secure, as only Trent will know the session key.

So Bob and Alice trust Trent! The key fundamental element of this, is that Bob never has to communicate with Trent, as he knows that the only person who has his key is Trent, so he is the only one able to encrypt the information contained within the information sent by Alice. Alice then cannot change her identity, as Bob will be able to determine this by checking what Trent has said is Alice’s identity is, with the identity that Alice produces, using the session key.

Conclusions

The core of security on the Internet — PKI — is flawed. We need new ways to define trust. Kerberos can be rather difficult to setup on a system, but it provides a more scaleable way to implement trust. Having your own trust architecture is much better than relying on someone else’s, as it is one of the most fundamentals parts of our data infrastructure.