Pretty Good Privacy and Box

Well, you get to the point in any applied cryptography, were you must cover the principles of public key encryption. Any there’s no better…

Photo by Kristina Flour on Unsplash

Pretty Good Privacy and Box

Well, you get to the point in any applied cryptography, were you must cover the principles of public key encryption. Any there’s no better way to show how symmetric key and asymmetric key (aka public key) can work together in perfect harmony than with PGP (Pretty Good Privacy).

Philip Zimmermann

In June 1991, Philip Zimmermann created the first release of PGP (v1.0) [here]:

In a GDPR era, Phil could see the future clearly:

PGP empowers people to take their privacy into their own hands. There has been a growing social need for it. That’s why I wrote it.

Phil Zimmerman was one of the first to face up to defence agencies with his PGP software, which, when published in 1991, allowed users to send encrypted and authenticated emails. For this, the United States Customs Service filed a criminal investigation for a violation in the Arms Export Control Act, and where cryptographic software was seen as a munition. Eventually, the charges were dropped.

Why doesn’t the community push for better standards? Well, could it be that the status quo is a comfortable place to be for many corporations, and where they can snoop on their employee’s emails?

Hal Finney — sadly departed — was also the second developer hired for the PGP Corporation, after Phil Zimmerman, and he is quoted that he loved the technology as it protected the rights of individuals to privacy. He remained there until his retirement in 2011.

Hal was completely enchanted by the magic of cryptography and his Web page announced:

Much of my free time and effort these days are devoted to my activities in cryptography. In the past, I have participated actively on the Cypherpunks mailing list. Cypherpunks Archives seem to go down suspiciously often; too much “burn before reading” stuff there, I guess.

and for PGP:

I was one of the original programmers on PGP version 2.0, working directly with Philip Zimmermann, author of the program. Today, I work for Network Associates, developing the crypto library for the commercial version of PGP.

In 2007 it took a step towards a standard as RFC 4880 [here] — note Hal Finney’s name on the list of authors:

How does PGP work?

With PGP we do not encrypt the data with public key encryption, for that symmetric keys are much more efficient. For this Bob takes a hash of the message, and then signs this with his private key. Next, he takes the message and the signature and then creates a new symmetric key (K). This is then used to encrypt both the data and the signature. Next, he takes Alice’s public key, and encrypts K. This encrypted key can then be added to the encrypted message:

To decrypt, Alice takes the encrypted key and decrypts it with her private key. She can then decrypt the message and reveal the signature. She can now read the message. To check it was Bob who sent the message, she checks the signature of the message with Bob’s public key and if the signature checks out, she knows it was Bob who sent it, and that it has not been changed:

Practical PGP

So let’s send a message of “So did NSA put a backdoor?” and we will apply a password of “qwerty” with 256-bit AES. With PGP we can encode to an armor file format, and which can be easily integrated into an email message:

To generate the key pair we use:

> gpg --keygen

We can then use GPG to generate the cipher message for the email. First, we create the message:

> type 1.txt
So did NSA put a backdoor?

Next, we create an amor file with the encrypted message:

> gpg -c -a 1.txt

We can then list the encrypted file:

> type 1.txt.asc
-----BEGIN PGP MESSAGE-----
Version: GnuPG v2jA0EBwMCz1yj3ME13Nae0lQBp7yb3F1PpsC6J0Qe/3UXsh0P4HIxKzslPdXROGrh
VtpKmtVUiLhEFFpHzdgEaFwCLBM/EP86dN7YVJBztoP/trM+Ib5j4buNv+EdGCra
X5YPeJc=
=BAb2
-----END PGP MESSAGE-----

This is the message that is pasted into the email. Finally, we decrypt with the given password:

> pgp -d 1.txt.asc
So did NSA put a backdoor?

PGP encryption with Go

So how can we send and receive secure email, without the complexity of public keys? Well, PGP has a symmetric encryption mode, and where we can use a symmetric key to encrypt and decrypt the message [example]:

package mainimport (
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/armor"
"golang.org/x/crypto/openpgp/packet"
)func main() { s:="hello world"
p:="hello world" s = string(os.Args[1])
p = string(os.Args[2]) plaintext := []byte(s)
password := []byte(p)
packetConfig := &packet.Config{
DefaultCipher: packet.CipherAES256,
} encrypted, _ := Encrypt(plaintext, password, packetConfig)
fmt.Println("Message: ", s)
fmt.Println("Password: ", p) fmt.Println("\nEncrypted:\n\n", string(encrypted)) decrypted, _ := Decrypt(encrypted, password, packetConfig) fmt.Println("\n\nDecrypted:", string(decrypted))
}
func Encrypt(plaintext []byte, password []byte, packetConfig *packet.Config) (ciphertext []byte, err error) { encbuf := bytes.NewBuffer(nil) w, _ := armor.Encode(encbuf, "PGP MESSAGE", nil)
pt, _ := openpgp.SymmetricallyEncrypt(w, password, nil, packetConfig) _, err = pt.Write(plaintext)
if err != nil {
return
} pt.Close()
w.Close()
ciphertext = encbuf.Bytes() return
}func Decrypt(ciphertext []byte, password []byte, packetConfig *packet.Config) (plaintext []byte, err error) {
decbuf := bytes.NewBuffer(ciphertext) armorBlock, _ := armor.Decode(decbuf)
failed := false
prompt := func(keys []openpgp.Key, symmetric bool) ([]byte, error) {
if failed {
return nil, errors.New("decryption failed")
}
failed = true
return password, nil
} md, err := openpgp.ReadMessage(armorBlock.Body, nil, prompt, packetConfig)
if err != nil {
return
} plaintext, err = ioutil.ReadAll(md.UnverifiedBody)
if err != nil {
return
} return
}

A sample run is:

-----BEGIN PGP MESSAGE-----wy4ECQMI702U/65IOE9gpkJvs7+uwZDJxWFcECcTu6/oBNBaBw4SuEW5mzx9Cxgu
0uAB5CeF3hCjroJ/9H719YeLxsjhbSPg3+Dv4TQl4ILiSsWvW+DE4uLOm3LgueCx
4NrkeW0yaNQw/tobiT6PnsCTEOIiZnJ74bH1AA==
=czPe
-----END PGP MESSAGE-----
Decrypted: hello

If we save the PGP message to a file name 1.asc, and then run “gpg -d 1.asc”, we can enter the password and read the message.

Box

The Box package works in a similar way to PGP email, and where Bob generates a symmetric key and uses the XSala20 encryption method to encrypt the message. Bob then takes a hash of this message, and encrypt it with his private key, and this is included in the encrypted message. Bob then encrypts the XSala20 key with Alice’s public key. He then send the encrypted message to her, and she will decrypt the key used to encrypt the message with her private key. She can then read them message. Now see checks the signature. For this she takes Bob’s public key, and then decrypts the hash. If she can decrypt it, she checks the hash against the hash that she gets, and if they are the same, she knows that it was Bob who send the message, and that the message is unchanged:

The Go Box package supports the encryption and authentication of short messages, using Curve25519, XSalsa20 and Poly1305. In this case we generate a public and private key for Bob and also for Alice. The public key is displayed as the x-co-ordinate of the public key point. The following is a sample of the code [here]:

package main
import (
"golang.org/x/crypto/nacl/box"
"crypto/rand"
"io"
"fmt"
"flag"
)

func main() {
flag.Parse()
args := flag.Args()
message:=args[0]
AlicePublicKey, AlicePrivateKey, _ := box.GenerateKey(rand.Reader)
fmt.Printf("Alice private %x\n",*AlicePrivateKey)
fmt.Printf("Alice public (x-co-ord) %x\n",*AlicePublicKey)
BobPublicKey, BobPrivateKey, _ := box.GenerateKey(rand.Reader)

fmt.Printf("\nBob private %x\n",*BobPrivateKey)
fmt.Printf("Bob public (x-co-ord) %x\n",*BobPublicKey)

var nonce [24]byte
io.ReadFull(rand.Reader, nonce[:])
msg := []byte(message)
encrypted := box.Seal(nonce[:], msg, &nonce, BobPublicKey, AlicePrivateKey)
var decryptNonce [24]byte
copy(decryptNonce[:], encrypted[:24])
decrypted, _ := box.Open(nil, encrypted[24:], &decryptNonce, AlicePublicKey, BobPrivateKey)
fmt.Printf("\nMessage: %s\n",message)
fmt.Printf("\nEncrypted: %x\n\n",encrypted)
fmt.Printf("Decrypted %s",string(decrypted))
}

The following is a sample run:

Alice private 3b4d6f7784b997ac262071c78a1a605af93f6e32e76ddeed3119fcabbd3b829f
Alice public (x-co-ord) 5c999ef6915b5cec518861303e67de37d9e1b842218c2820cebff4e547912329Bob private aa1ba56956c75523c8a7f926d0356989c040ea7092cd7d16d25d1aadddda09da
Bob public (x-co-ord) b70cfc4613bf35eed81d58a5d211e4197d207c1a88ee494a3ecd4bd5d85dcb26
Message: abc
Encrypted: 06686a97f5e4fb11d9c90befac2d283cc5730df6942e58d6e6548a3b76c7dd17a4d107a525ca468a85e98d
Decrypted abc

Conclusions

Email has been around for decades, and it is still the Number 1 threat in cybersecurity. Most of what we receive is untrusted and unsigned, and there’s no way to tell if an email has been read or not and if it has been changed.

If you want to learn more, try here:

https://asecuritysite.com/pgp