GPG: Encryption, Decryption & Digital Signature with Public & Private Key [A Complete Tutorial]

GNU Privacy Guard (GnuPG or GPG) is a free cryptographic software that can secure data transfer and communication between two parties by encrypting, signing and verifying data.

Public Key Cryptography

GnuPG uses public-key cryptography to communicate securely between two parties. In a public-key system, each user has a pair of keys: a private key and a public key. A user’s private key is always kept secret. The public key may be given to anyone with whom the user wants to communicate. Suppose, if I (sender) have your (receiver) public key then I can encrypt a message or document with your public key and send it to you. You can then decrypt that message or document with your private key. In fact, the message or document encrypted by your public key can only be decrypted by your private key.

So, in this public-key encryption system, if I want to send you an ecrypted document then I should have your public key. Similarly, if you want to send me an encrypted document then you should have my public key.

Validating the Sender

Suppose, you sent me an ecrypted document. But, how can I be sure that the document was originally sent by you? Someone can have tampered/modified the document in between.

In public-key systems, this kind of verification and validation can be done with the help of digital signature. Digital signature certifies and timestamps a document. Both public and private keys are involved in creating and verifying a digital signature on a document. Sender can sign on the document (i.e. create digital signature on the document) using his/her private key. Receiver can verify the signature using the sender’s public key. If the document is modified after sender has signed on the document, then the verification of the signature will fail.

Installing GPG

I am using Ubuntu Linux Operating System. GPG is installed by default on Ubuntu. You can check its installed version by typing the following command:


gpg --version

If GPG is not installed in your Ubuntu system then you can install it with the following command:


sudo apt-get install gnupg

Generating GPG Keys

You can generate your GPG keys with the following command:


gpg --gen-key

This will ask few questions before generating the keys.

First question is about what kind of key you want. I selected the default one, i.e. RSA and RSA.

Please select what kind of key you want:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
Your selection? 1

After that, you will be asked about your choice of keysize. I went with the default keysize, i.e. 2048.

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
Requested keysize is 2048 bits

Then, you need to specify the expiration time for your keys. You can specify the expiry time in number of days, weeks, months, or years. If you enter 0, then your key will never expire. I went with the default value, i.e. 0.

Please specify how long the key should be valid.
0 = key does not expire
= key expires in n days
w = key expires in n weeks
m = key expires in n months
y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y

After that, you need to enter your identification (your real name, email address and an optional comment). Comment can be your title, position, designation, nickname, etc. I didn’t enter anything for comment.

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
“Heinrich Heine (Der Dichter)

Real name: Your Name
Email address: your.name@example.com
Comment: Optional Comment
You selected this USER-ID:
“Your Name (Optional Comment)

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
You need a Passphrase to protect your secret key.

Finally, a popup box will appear asking for a Passphrase to protect your secret key. This passphrase is required when you are using your private key to either decrypt or sign any message or document. Enter the passphrase which you can remember for long time. You need to save your passphrase in a safe place (either in your computer or in your email) so that you can search it there in case you forget it in future.

Viewing your keys

You can view your newly created key using the following command. This will generate all the public keys on your public keyring.


gpg --list-keys

You can view your secret key using the following command:


gpg --list-secret-keys

The output will be like below:

pub 2048R/C5DB61BC 2015-04-21
uid Your Name (Optional Comment)
sub 2048R/18C601D3 2015-04-21

Note: C5DB61BC is the key ID.

Generate Revocation Certificate

After your keypair is created, you need to generate and save the revocation certificate for your public key. This is very useful in case you forget your passphrase or you lost your private key. In such case, you can publish your revocation certificate and let other users know that the public key should no longer be used for encrypting any message/document. However, other users can still verify signatures made by you in the past using your revoked public key. You can also decrypt messages/documents sent to you in the past if you have your private key (which is related to your revoked public key).

The following command will generate revocation certificate in your terminal. You need to manually copy and save it in a file.


gpg --gen-revoke mykey

If you want to save it directly to a file then you can do so with the following command. This will save the revocation certificate in revoke.asc file.


gpg --output revoke.asc --gen-revoke mykey

Here, mykey is the key specifier. This can be your key ID or any part of the user ID like user’s name (with inverted comma) or email address.

So, you can run it as:


gpg --output revoke.asc --gen-revoke "Your Name"

OR,


gpg --output revoke.asc --gen-revoke your.name@example.com

OR,


gpg --output revoke.asc --gen-revoke KeyID

While generating the revocation certificate, you will be asked the reason to create it. You can select 0 (No reason specified) and then enter some option description if you like. After that you can confirm it and your revocation certificate will be generated.

Here is the revocation certificate output:

—–BEGIN PGP PUBLIC KEY BLOCK—–
Version: GnuPG v1
Comment: A revocation certificate should follow

iQEfBCABAgAJBQJVNiWbAh0AAAoJEK5iEkLF22G86XQIAIk8llTFcwMUH3mgk2Z8
zlfn0ToYQbPp2q89U9WMYe41rSoolUl5YmLbS8bEMm4vwH8ih/d+Otsd2N+KwyIj
ewdO2tFmbf53Gyck3emAUEqW/W9ngCdvTs34oHoIn9TyXbl2hhqTnQTmxbGv68J1
nk7N68A8nMAhxOlDDMgUL18ZeaEzRoB2P2Xkl+F/AjMbdhPR5mm73dwNcEfnjKJa
B1eVB+wlp+b/FCfriJolFSw3IKQwsZOB+if7MekiBc0a3CH09wDn+VxD7QMqIoim
TW2l4n2Z34IkSWktq0x8alnCsynB86ieAiDQyP56CzaWCcgJc8YlkJO8aLbUIQIe
Rdw=
=ogiv
—–END PGP PUBLIC KEY BLOCK—–

Exporting your public key

You need to first export your public key into a file. After that, you can send that file to the other person who can use it (your public key) to encrpyt document before sending the document to you.

The following command will export your public key in ASCII-armored format to a file named your-name.asc.


gpg --armor --output your-name.asc --export your.name@example.com

You can then send this file your-name.asc (your public key) to other person who can encrpyt document using it.

Your public key export should look like this:

—–BEGIN PGP PUBLIC KEY BLOCK—–
Version: GnuPG v1

mQENBFU2H5EBCADHpjlGHAgquXTf2Xf51GH+e13CBBTVI/mdI5/B1OKB07LQ0zLD
SfvB6FbJeGbPGW+f4zzvPRn5hyDp6d2qG6utQMtoifhZHBZrT0RW8CuHG4P9dg6S
1PJWtXh1dNeQp0hEjfdFRoOykX3nRRno9alzOc6QMAszqevNDYab24PIPZoUkiAu
REEu8rBGTLptkbwIHWw8styFoY80QPNAZLLlnNtHEI+QrOYnxLOGXHX0pK5Y0YFm
0Pz4WCmYTvTiOXQFBHTaZnuZVE8xAJL54odj2WV7JsDNjO37VRekGUfV/bFc24u+
0Vexm8k4itx7WjbvPSa+rtSuoTm3spOnU1cFABEBAAG0NFlvdXIgTmFtZSAoT3B0
aW9uYWwgQ29tbWVudCkgPHlvdXIubmFtZUBleGFtcGxlLmNvbT6JATgEEwECACIF
AlU2H5ECGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEK5iEkLF22G87S4H
/1S4bfGK+R6BOu2O4zkNKvFC21hk8YXrzoO5HFvOY0eNOoyv/6ElrpDfYXdRmZM7
5/mlLsjVcjUOosFVBNb0sgufIks+GuEgrs/j/U+gxeEB3RDmQlUjFGr2xyMResA3
mWeGBGRLn7coiDTAJh4G1pUCWKMpPF0K9BJLrGPlNr2wr/h+GQVSyaT4KAEBXnAX
P2XnVioZfh2jGfdTWNfX/mjVeHvf1F9yLjrTz72aWfFwMRGW25R8lLqaHLhizcMq
Xa4M/M0UMAE7sNX/un/GHNJL6oHKyx3bqnYTXb3Cv5nQjUyq2wJxyiJJIzD4P9Zx
yuot9BeBvvbH9cG2HfvLqIO5AQ0EVTYfkQEIAKDuxzj8czwhdm2R1MRibEC2YuoK
he61nZKpRWPSXOF5Inb/qc2n3CeF8aG6Te9yNXmF08ou1bpmRiQsrTWqtccejFLs
APqVwm4/3t8ADguEDo6odUs4vtZ3K+F5CI0X4OCVf2mXvx4R17TdntH35+W0ytLF
dM7LiL9L0ZZe6N3DDXgvx8rbS1W0ZjMn63etmKNgW3E7LbyiEqE6B0JviYilGQcC
Ecx+G85nsuL1oOxjtmu/IRJ+SE/7+m35fAbL+Rst3FTizG5HBAGFoSuddie6ig/j
PkAVU7ENG1oTfCRtIZ+CLPvql6IauO6qNw9/I9QKKd7jTCd1m4ErjkCftUcAEQEA
AYkBHwQYAQIACQUCVTYfkQIbDAAKCRCuYhJCxdthvFSXB/93zpjcuxfSFSwM7r0i
wYKQzOjjhq3iYai5qazZi204tDEExTMYnZGi68FscWH8IHbHE7ZzRdyNJMrt55AN
zMycESjKx1r1n9nlRuLyxQXseOhtbdrtMSQ28fbyfJcwIJcyIgWfk39RvI0l2F4I
PFfkNZejH4Uea7xtbeUjyjLKUoNI7bJJLxpRbNw0mbUnrP4dUR8hYTiITzZjJtXM
FJ1N87lhpNzJ4oZPl5tN0+V4xaM9nQUBnM7eCOmmYOeXopASYtGhKrxToeUn06I2
z8In6vlomcse6S4d8ruCLBvuJSKLNSgS9ox96R2vD07aciOJF31twAo35w/DMXXi
mwgk
=SP6Q
—–END PGP PUBLIC KEY BLOCK—–

Exporting your private key

Your private/secret key is stored in your computer. If your OS or hard disk gets corrupted then you may lost your private key. It is better you export your private key and save it in a secure location so that you can import it a new system.

List your keys with –list-keys command.


gpg --list-keys

You will get the output like below:

pub 2048R/C5DB61BC 2015-04-21
uid Your Name (Optional Comment)
sub 2048R/18C601D3 2015-04-21

In the above key example, your key-ID is C5DB61BC. You can use this key-ID to export private/secret key related to this key-ID.

Here is the command to export the private key in ASCII format:


gpg --armor --output secret.asc --export-secret-keys key-ID

From the above command, your secret key will be exported in secret.asc file.

Importing other’s public key

You can add other peoples’ public key into your public keyring. For this you need a file containing other person’s public key. You can import the public key with the following command. The file-name can be in .gpg, .asc, or any other extension.


gpg --import file-name

You can then check the list of keys with the following command:


gpg --list-keys

Distributing your public key

It is better to let other people know about your public key so that they can easily get your public key and then they can use it to encrypt document and send it to you.

You can export your public key as a text file and then upload it to any online file server. Then, you can publicize it by:

1) Putting the online link of your public key on your website/blog etc.
2) Putting the online link of your public key on your email signature.
3) Uploading your public key on online key-servers

There are different online key-servers where you can upload/store your public key(s). You can also search for or download other peoples’ public key from these key-servers. These servers are called HKP Keyserver named after a web-based OpenPGP HTTP Keyserver Protocol (HKP).

Here is a list of some popular key-servers:

keys.gnupg.net
subkeys.pgp.net
pgp.mit.edu
pool.sks-keyservers.net
zimmermann.mayfirst.org
keyserver.ubuntu.com

pgp.mit.edu is a popular keyserver maintained by MIT itself.

To store/upload your public key on this key server, you can run the following command:


gpg --send-keys --keyserver pgp.mit.edu Your-Key-ID

Note that: In the following example, the key ID is C5DB61BC.

pub 2048R/C5DB61BC 2015-04-21
uid Your Name (Optional Comment)
sub 2048R/18C601D3 2015-04-21

You can search for others’ public key in the MIT key server using the following command:


gpg --keyserver pgp.mit.edu --search-keys search-parameter

The search-parameter can be any name, email address, or key ID.

Verifying other person’s public key

You need to verify that the public key you have is actual public key of the person whom you want to send the encrypted document. For this, you can check the fingerprint of the public key you have and ask the person personally, by phone, by email, or by other means and verify if his/her public key has the same fingerprint.

After you have imported other person’s key into your public keyring, you can get the fingerprint of that public key by running the following command. Suppose, the other person’s email is “other-person@example.com”:


gpg --fingerprint other-person@example.com

You can check your public key’s fingerprint with the following command:


gpg --fingerprint your.name@example.com

Alternative way to check fingerprint:


gpg --edit-key your.name@example.com
gpg> fpr

Sign and confirm other person’s public key

After you have verified the fingerprint of the other person’s public key, you can then sign that public key which indicates that you have verified and you trust the public key.

Suppose, the other person’s public key has email as “other-person@example.com”, then you can sign that public key with the following command:


gpg --sign-key other-person@example.com

Alternative way to sign key:


gpg --edit-key your.name@example.com

# Sign the key
gpg> sign 

# Check signature(s) in the key
gpg> check

After you sign the other person’s public key, you can export that public key and send it to that particular person. The other person can then import the public key signed by your in his system. Signing a public key by many people will increase the trust of the public key.

You will export and send the .asc file to the other person.


gpg --armor --output file-name.asc --export other-person@example.com

The other person will receive the file you sent and then he/she will import it to his/her system.


gpg --import file-name.asc

Encrypting and Decrypting documents

Encrypting

– Receiver’s public key is used to encrypt the document.
– Encryption is done by the sender.

Decrypting

– Receiver’s private key is used to decrypt the document.
– Decryption is done by the receiver.

Suppose, I want to send an encrypted document named “testdoc” to another person. For this, I will download/get his/her public key and import it to my public keyring. Suppose, the public key email is “other-person@example.com”. Now, I will use the following command to encrypt the document. The encrypted output file is named “testdoc.gpg”.


gpg --output testdoc.gpg --encrypt --recipient other-person@example.com testdoc

Now, I will send that encrypted doc to the other person. He/She will receive the file, download it and run the following command to decrypt it. The decrypted output file is named “testdoc2”.


gpg --output testdoc2 --decrypt testdoc.gpg

While decrypting, the receiver will need to enter his/her passphrase of his/her secret key.

Digitally signing a document

A digital signature helps to protect a document from tampering/modifying done by attacks like man-in-the-middle attack. The verification of the signature will fail if the document is modified in the middle of the communication between two parties.

Public-Private key-pair is used to digitally sign a document. Private key is used to sign the document and Public key is used to verify the signature.

The following command will digitally sign the document. Digitally signed output file is named “testdoc.sig”. The output is in binary format.


gpg --output testdoc.sig --sign testdoc

Following command is used to decrpyt the signed document. The output file is named “testdoc3”.


gpg --output testdoc3 --decrypt testdoc.sig

You can only verify the signature using the following command:


gpg --verify testdoc.sig

The above signature commands will generate the output in binary format. If you want to generate the output in ASCII-armored format then you can use –clearsign command. This will not modify the document but will just wrap the document in the signature.


gpg --output testdoc4 --clearsign testdoc

Thanks for reading.