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 Eve
. 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 my-email-id@domain.com
The armor
flag is optional, it just outputs the file in ASCII armored/ normal text format.
The 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 my-email-id@domain.com
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. my-public-key.gpg
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 example@example.com myfile.csv
# file
will get generatedmyfile.cs
v.gpg
or gpg --output encryptedfile.gpg --encrypt --recipient example@example.com myfile.csv
# file encryptedfile.gpg
will get generated because of output
flag
Assumptions:
– The file myfile.csv
exists in your current directory
– We have already imported the public key of the person whose email id is example@example.com
This will encrypt the file myfile.csv
using the public key of person example@example.com
and output a new file myfile.csv.gpg
. Now this file myfile.csv.gpg
can only be decrypted by the person example@example.com
. 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 example@example.com
Decrypting a file or a message using gpg
gpg --decrypt encrypted-file.gpg
# this will display our decrypted file contents to standard output screengpg --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 signaturegpg --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 signaturesgpg --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
The 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 example@example.com my-file.csv
# outputs a new filesigned-encrypted-file.gpg
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 sign
and 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