1. Overview
Encryption is the process of encoding data with the intent of keeping it safe from unauthorized access.
In this quick tutorial, we’ll learn how to encrypt and decrypt files in Linux systems using GPG (GNU Privacy Guard), which is popular and free software.
2. Basics of Encryption
Before we start, let’s try to understand some basic concepts.
Basically, all types of encryption (and decryption) primarily involve either a passphrase or a key, which are simply data strings.
2.1. Types of Encryption
Depending on the number of data strings involved in the encryption and decryption process, we have two kinds of encryption.
When only one data string – a passphrase – is used for both encryption and decryption, it’s called symmetric encryption. We generally use symmetric encryption when we don’t need to share the encrypted files with anyone else. If we do share, then we’d need to share the passphrase as well, which can be a potential risk factor.
On the other hand, when two data strings are involved, one for encryption and another for decryption, it’s called asymmetric encryption. Accordingly, the pair of data strings are called key pairs.
Asymmetric encryption is more suitable for the sharing of encrypted files, as it requires sharing only one of the two data strings. We’ll discuss this later in the tutorial.
2.2. Types of Keys
In asymmetric encryption, a key pair consists of two keys — a public key and a private key.
The public key is not confidential. Therefore, we can share the public key with stakeholders without any risk.
On the contrary, we should always keep the private key a secret and never share it with anyone.
Public keys are always used for encryption and private keys for decryption when it comes to data encryption/decryption.
It might be worthwhile to know that public/private keys can also be used in the field of digital signatures. In such cases, we use the private key to create the signature and its corresponding public key to verify its authenticity.
3. GPG Installation
Let’s open a terminal window and check if GPG is installed:
> gpg --version
gpg (GnuPG) 2.2.4
If it’s not installed, let’s go ahead and install it using the package manager of our Linux distribution.
For apt based distributions:
> sudo apt install gnupg
Or, for yum based distributions:
> sudo yum install gnupg
The GPG tool comes with both GUI and CLI, but we’ll be using the command line for our examples.
Additionally, we’ll be using the appropriate options to run the commands in unattended mode.
4. Symmetric Encryption
4.1. Encrypting Files
Let’s now try encrypting a file by first creating a sample file:
> echo "Hello, Baeldung!" > greetings.txt
Next, let’s run the gpg command to encrypt the file using a passphrase:
> gpg --batch --output greetings.txt.gpg --passphrase mypassword --symmetric greetings.txt
Subsequently, this will create the encrypted file greetings.txt.gpg in the same location using the default AES256 algorithm. To use a different algorithm, we can use the option —cipher-algo.
4.2. Decrypting Files
Let’s now try to decrypt the encrypted file from the previous example:
> gpg --batch --output greetings1.txt --passphrase mypassword --decrypt greetings.txt.gpg
gpg: AES256 encrypted data
gpg: encrypted with 1 passphrase
This will create the decrypted file greetings1.txt in the same location.
Note that if we omit the –batch option, the system prompts us to enter the passphrase and then stores it in the session.
Therefore, to clear the password stored in the session, we can run:
echo RELOADAGENT | gpg-connect-agent
Let’s now get back to our decrypted file and verify that the decryption was successful:
> diff -s greetings.txt greetings1.txt
Files greetings.txt and greetings1.txt are identical
5. Asymmetric Encryption
In this type of encryption, there are two roles involved — a sender and a receiver.
The receiver decrypts the received file. Thus, the receiver is responsible for generating the key pair. Above all, the receiver would safely keep the private key secret and share only the public key with the sender.
The sender encrypts the file to be sent using the public key shared by the receiver.
Let’s see how this works using an example where Ryan is the receiver, and Sam is the sender.
To simplify things, let’s create two work folders for each of them, which, in the real-world, would represent two different systems:
> mkdir ryan
> mkdir sam
5.1. Generating a Public/Private Key Pair
The first step is for Ryan, as the receiver, to generate a key pair in his folder:
> cd ryan
> gpg --batch --generate-key <<EOF
Key-Type: RSA
Key-Length: 3072
Subkey-Type: RSA
Subkey-Length: 3072
Name-Real: Ryan
Name-Email: [email protected]
Passphrase: ryanpassword
Expire-Date: 30
%pubring ryanpubring.kbx
%commit
EOF
This will generate the key pair and store it in the ryanpubring.kbx keyring file in the same location.
Let’s view the public key entry made to the keyring file:
> gpg --keyring ./ryanpubring.kbx --no-default-keyring --list-keys
./ryanpubring.kbx
-----------------
pub rsa3072 2019-10-27 [SCEA] [expires: 2019-11-26]
120C528F1D136BCF7AAACEE6D6BA055613B064D7
uid [ unknown] Ryan <[email protected]>
sub rsa3072 2019-10-27 [SEA] [expires: 2019-11-26]
The pub indicator is for the public key.
Similarly, we can view the private key entry:
> gpg --keyring ./ryanpubring.kbx --no-default-keyring --list-secret-keys
./ryanpubring.kbx
-----------------
sec rsa3072 2019-10-27 [SCEA] [expires: 2019-11-26]
120C528F1D136BCF7AAACEE6D6BA055613B064D7
uid [ultimate] Ryan <[email protected]>
ssb rsa3072 2019-10-27 [SEA] [expires: 2019-11-26]
Here, sec indicates that this is a secret or private key.
5.2. Sharing Public Key
After a successful key generation, Ryan can export the public key from his keyring into a file:
> gpg --keyring ./ryanpubring.kbx --no-default-keyring --armor --output ryanpubkey.gpg --export [email protected]
This will generate a new file ryanpubkey.gpg containing the public key. Let’s take a peek at the file content:
> cat ryanpubkey.gpg
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQGNBF21KQoBDACs7bgjl22TPyQDKjLTMlZrBgQrXZOIkNcH3z1f87XQYoLjVPU3
ymg1hweHm1RsIxO+GdD42pkU/ob5YdWgvVBRdIZPeTXciTa8TtxZKNNtr+IL0pwY
...
-----END PGP PUBLIC KEY BLOCK-----
Ryan can now share this file with Sam via secured or unsecured channels.
In our example, let’s do a simple file copy for sharing the public key:
> cp ryanpubkey.gpg ../sam
5.3. Importing Public Key
Let’s now see what Sam has to do after receiving the public key from Ryan.
First, let’s switch to Sam’s folder:
> cd ../sam
Then, let’s import Ryan’s public key into Sam’s keyring file:
> gpg --keyring ./sampubring.kbx --no-default-keyring --import ryanpubkey.gpg
gpg: keybox './sampubring.kbx' created
gpg: key D6BA055613B064D7: public key "Ryan <[email protected]>" imported
gpg: Total number processed: 1
gpg: imported: 1
gpg: public key of ultimately trusted key 01220F5773165740 not found
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 2 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 2u
gpg: next trustdb check due at 2019-11-26
This will create a new keyring file sampubring.kbx and add the public key to it.
We can now view the imported key:
> gpg --keyring ./sampubring.kbx --no-default-keyring --list-keys
...
uid [ unknown] Ryan <[email protected]>
The [ unknown] indicates that information regarding the key’s trustworthiness is not available. To avoid warnings in the future, let’s change this to trusted:
> gpg --keyring ./sampubring.kbx --no-default-keyring --edit-key "[email protected]" trust
In the trust level question that is asked, let’s specify our choice as 5 = I trust ultimately and confirm as yes. After that, let’s type quit to exit from the shell.
5.4. Encrypting Files
Sam is now all set to encrypt a file that only Ryan can read. Let’s create a sample file:
> echo "Hello, Baeldung!" > greetings.txt
Afterward, let’s specify Ryan as the recipient in the encrypt command:
> gpg --keyring ./sampubring.kbx --no-default-keyring --encrypt --recipient "[email protected]" greetings.txt
This creates the file greetings.txt.gpg in the same location and encrypted using Ryan’s public key. Sam can now share this file with Ryan via secured or unsecured channels.
As before, let’s do a simple file copy for sharing the encrypted file:
> cp greetings.txt.gpg ../ryan
5.5. Decrypting Files
Let’s now return to Ryan’s folder to read the encrypted file he received from Sam:
> cd ../ryan
We can use the decrypt command:
> gpg --keyring ./ryanpubring.kbx --no-default-keyring --pinentry-mode=loopback --passphrase "ryanpassword" --output greetings.txt --decrypt greetings.txt.gpg
gpg: encrypted with 3072-bit RSA key, ID 8273FAC75696D83E, created 2019-10-27
"Ryan <[email protected]>"
This will create a new file greetings.txt decrypted using Ryan’s private key.
We can quickly check if decryption was successful:
> diff -s greetings.txt ../sam/greetings.txt
Files greetings.txt and ../sam/greetings.txt are identical
5.6. Two-Way Communications
In the previous example, the communication is unidirectional, as the sender and receiver roles are static.
What this means is that for enabling bidirectional communication, all we need to do is reverse the roles by generating a second key pair. We can follow the same steps listed in the previous section.
6. Conclusion
In this article, we learned how to encrypt files using two different approaches so that, depending on the requirement, we can decide upon the most suitable one for the task.
We also learned about public/private keys and how to use them practically for file encryption/decryption.