by Tejaas Solanki

Want to understand Pretty Good Privacy? Simulate it.

Photo by Bernard Hermant on Unsplash

As the name suggests, Pretty Good Privacy (or PGP) is an encryption program that actually provides pretty good privacy. The “pretty good” bit is meant to be a bit of an ironic understatement. It has been one of the dominant forms of end-to-end encryption for email communications after its development by Phil Zimmermann in 1991. It became increasingly popular after its use by whistleblower Edward Snowden.

PGP provides two things essential for a secured communication:

  1. Confidentiality: Provided through the use of symmetric block encryption, compression using the ZIP algorithm, and E-Mail compatibility using the radix64 encoding scheme
  2. Authentication: Provided through the use of digital signatures

Without further ado, let us get to the workings of PGP.

How it works

I will be explaining the concept of PGP from the point of view of the implementation in the context of Alice (the sender) and Bob (the receiver). We will be using the following algorithms:

  1. RSA as the asymmetric encryption algorithm
  2. SHA-512 as the hashing algorithm
  3. DES as the symmetric encryption algorithm and
  4. ZIP for compression

You can use other algorithms as well. (I know DES is too old to be used but the goal here is to understand the concept of PGP.)

The PGP Process

Alice and Bob both generate their pair of keys (Public and Private Keys) using the RSA algorithm. Public keys of Alice and Bob should be known to each other.

Alice’s / Sender’s Side:

  1. Alice writes a message M, which she intends to send to Bob.
  2. M is provided as an input to the SHA-512 algorithm to get the 512 bit binary hash (represented as 128 bits hexadecimal string) of it.
  3. This hash is digitally signed by using RSA algorithm i.e. the hash is encrypted by the private keys of Alice. The inputs to RSA are Private Keys of Alice and the hash. The output from RSA is the digitally signed hash or encrypted hash EH.
  4. Now, M and EH are appended together. (Appended in the sense that they are put in an array of strings).
  5. M and EH (which are in an array of strings) act as input to the ZIP compression algorithm to get the compressed M and compressed EH, again in an array of strings.
  6. The output of the above step is now encrypted using the DES symmetric encryption algorithm. For this, we will first generate the SecretKey for DES. This key and the output of step 5 will act as input to the DES encryption algorithm which will provide us an encrypted output (again in an array of strings).
  7. Last but not the least, since M is encrypted using SecretKey, it also has to be sent to Bob. We will encrypt the SecretKey of DES algorithm with the Public Key of Bob. We will use RSA for this and the inputs to it will be the Public key of Bob and SecretKey.
  8. The outputs of steps 6 and 7 are now appended and sent as the final message to Bob.

The whole message is sent as an array of strings (String finalmessage[]) which contains the following at indices:

0: Compressed message M which is encrypted with the SecretKey

1: Digitally signed hash EH which is then compressed and encrypted with the SecretKey

2: Output of step 7

Bob’s / Receiver’s Side:

  1. Bob will first decrypt the SecretKey of DES with his Private Keys. The inputs to RSA algorithm for this will be Private Keys of Bob and finalmessage[2]. The output from RSA will give Bob the SecretKey.
  2. This SecretKey will now act as one of the inputs to DES decryption algorithm for decryption of finalmessage[0] and finalmessage[1]. These two will also act as the inputs to DES decryption algorithm. The output of this step will be decrypted version of finalmessage[0] and finalmessage[1].
  3. The outputs of the above step should be provided as input to the ZIP algorithm for decompression.
  4. From the output of the above step, we will get the digitally signed hash and the original message M. We will verify whether the hash was signed by Alice. For this, we will calculate the hash of the original message M by using SHA-512 (calculated_hash). We will also decrypt the digitally signed hash with the public keys of Alice by using RSA.(Inputs to RSA: digitally signed hash and public keys of Alice and Output from RSA: decrypted_hash).
  5. Compare the decrypted_hash and calculated_hash. If they turn out to be the same, then authentication is achieved which means that the message was indeed sent by Alice.

The following is the simulation of PGP done in the simplest way using Java.

We have used the base64 encoding scheme which is similar to radix64 that is used in PGP.

Note:

  1. We base64 encode the strings after encryption and compression so as to get a readable text form.
  2. For decryption and decompression, we send the base64 decoded inputs as the actual inputs to the decryption and decompression algorithms.
  3. The key has been base64 encoded and decoded since I have used Java for simulation of PGP, which requires encoded form at the receiver side so that it can be converted to SecretKey datatype for decryption process.

Please follow, clap and share. Comment for any mistakes or improvements or suggestions. You can even follow me on Twitter.