Public key, also known as asymmetric encryption involves two keys i.e. public key and private key. It helps two parties to communicate with each other in a much secure way.
The whole process can be described as follows:
Adam wants to send a secret message to his friend
Eve. Both have generated keys in their machines using the command
gpg --gen-key. So Both have a set of “public key and private key”. In order to securely send the message,
Adam will need
Eve‘s public key. Why? To encrypt the message with this public key. This encrypted message can be decrypted only with the private key of
Adam is safe to send this encrypted message via the internet because it is nearly impossible for anyone to decrypt this message provided the private key of
Eve is not compromised.
List and generate keys
Go to your terminal and type
gpg --list-keys. This will print all keys in your keyring. This list includes your own keys(if already generated) and all imported keys.
gpg --gen-key – We can use this to generate a public-private key pair. It will ask some questions like name, email, etc.
Exporting and importing keys
We can export our public key(Private key is supposed to be with you only and not to be distributed) to a file using gpg’s export option like so:
gpg --armor --output my-public-key.gpg --export email@example.com
armor flag is optional, it just outputs the file in ASCII armored/ normal text format.
output flag is necessary here. If not mentioned then our key will be output to the standard output rather than to a file.
Now we can distribute the file
my-public-key.gpg to other people, and they can import this key in their key-ring. After importing they can see our public key when hitting the command
gpg --list-keys on their machine.
Note1: If we want to export anyone else’s public key, then we will need to replace
firstname.lastname@example.org with their corresponding email id.
Note2: Email id is used to identify the keys, we can also use public key id instead of email id. Public key id can be extracted from the fingerprint of the public key.
gpg --list-keys shows a long text something like
ET99B6FEEG1704H6A86VD9MC9A77225Q43590LD6, this is the fingerprint of the public key. The last eight characters is the public key id.
A public key can be imported using gpg’s
import option. For example in the above case, people can import our public key using gpg’s import option and mentioning the file that we have distributed i.e.
gpg --import my-public-key.gpg
# this will add a new public key in the key-ring.
Encrypting a file or a message using gpg
gpg --encrypt --recipient email@example.com myfile.csv
will get generated
gpg --output encryptedfile.gpg --encrypt --recipient firstname.lastname@example.org myfile.csv
encryptedfile.gpg will get generated because of
– The file
myfile.csv exists in your current directory
– We have already imported the public key of the person whose email id is
This will encrypt the file
myfile.csv using the public key of person
email@example.com and output a new file
myfile.csv.gpg. Now this file
myfile.csv.gpg can only be decrypted by the person
firstname.lastname@example.org. Why? … because we encrypted the file using his public key and only he has the corresponding private key which can decrypt the encrypted file.
--recipient option means that you want to encrypt our message/ file for the person whose email id comes after
--recipient. In this case, the recipient is
Decrypting a file or a message using gpg
gpg --decrypt encrypted-file.gpg
# this will display our decrypted file contents to standard output screen
gpg --output my-decrypted-file --decrypt encrypted-file.gpg
# this will create a new file
my-decrypted-file holding the decrypted content
Signing and verifying signatures in gpg
We know that in
gpg, we can encrypt a file using a public key and then it can be decrypted using the corresponding private key. However, we can do it in the opposite way also i.e. we can encrypt a file using a private key and then it can be decrypted using the corresponding public key. This is known as signing. Signing is not same as encryption.
When we encrypt a file using a public key, nobody can decrypt except the recipient(only recipient has the private key). That means encrypting a file using a public key assures that file is meant for someone(recipient).
When we sign a file using our private key, everybody can decrypt(decrypt here means verify the signature) the file because all those who have our public key can do it. That means signing a file using our private key assures that the file came from us(if not then our private key is compromised)
gpg --sign myfile.csv
# this will output a new
myfile.csv.gpg which holds both the original file and the signature
gpg --output signed-file.gpg --sign myfile.csv
# this will create a new file
signed-file.gpg signed by our private key
Note: we don’t need to mention our private key in the above command, gpg will automatically use our private key(assuming we already have generated the public-private key pair).
Now the file
signed-file.gpg is a signed file, we can send it to our friend through the internet. If our friend is able to verify the file using our public key, then it assures that the file came from us because we signed the file with our private key and we know that only our public key can decrypt/ verify it.
gpg --verify signed-file
# if the file is really from us, then our friend will get an output of something like
gpg: Good signature
We can also use
decrypt option instead of
--verify to verify signatures
gpg --decrypt singed-file
# this will verify the file, decrypt it and display the original contents of the file to our standard output.
gpg --output decrypted-file --decrypt singed-file
# this will verify the file, decrypt and create a new file
decrypted-file holding the original contents
decrypt flag works like this:
– If the file has no signature, it will just decrypt the file.
– If it has a signature but we don’t have the public key, it will decrypt the file but it fail to verify the signature.
– If it has a signature and we have the public key, it will decrypt and verify.
Signing and encrypting a file
We learnt how to encrypt a file and sign a file. How about sending a secret file/ message in a more secure and trusted way? Encryption ensures that nobody spies on our secret message. Signing ensures that the secret file is indeed from us. Having both i.e. signing and encrypting a file ensures that the secret file has not been spied upon and it is indeed from us!
gpg --output signed-encrypted-file.gpg --sign --encrypt --recipient email@example.com my-file.csv
# outputs a new file
The above command will first sign the file with our private key and then encrypt the signed file with the recipient’s public key.
Note: The order of
encrypt flag doesn’t matter.
gpg will always sign and then encrypt the file
This file can be then verified and decrypted with a single command like this:
gpg --output decrypted-file --decrypt signed-encrypted-file.gpg