File encryption/decryption using GPG

There are just too many people and organizations who are interested in our data. Thus, the secure transmission of data is important. Through encryption/decryption, data can be protected from access by third parties. There are already very long easy ways for the encryption/decryption but I have to find again and again that these are quite unknown. Herewith a little tutorial where I want to show possibilities by means of GPG.

Requirements

  • Docker (latest)

Environment preparation

By means of two Docker containers, we now want to simulate 2 persons who exchange the encrypted data.

# prepare project
$ mkdir -p ~/Projects/GPG-Example && cd ~/Projects/GPG-Example

# pull latest centos image (optional)
$ docker pull centos

# start container (user_a)
$ docker run -d -ti --name user_a --mount type=bind,source="$(pwd)",target=/share centos /bin/bash

# start container (user_b)
$ docker run -d -ti --name user_b --mount type=bind,source="$(pwd)",target=/share centos /bin/bash

# check running containers (optional)
$ docker ps -a

# enter container (user_a eq. terminal 000)
$ docker exec -ti user_a /bin/bash

# enter container (user_b eq. terminal 001)
$ docker exec -ti user_b /bin/bash

Container (user_a)

# show version (optional)
$ gpg --version

# create a simple text file
$ echo -e "Lorem ipsum dolor sit amet,\nconsetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,\nsed diam voluptua." > /share/example.txt

# print file in STDOUT (optional)
$ cat /share/example.txt

# symmetric encryption
$ gpg -c /share/example.txt && rm -f /share/example.txt

# check directory (optional)
$ ls -la /share/

Container (user_b)

# symmetric decryption
$ gpg -d -o /share/example.txt /share/example.txt.gpg && rm -f /share/example.txt.gpg

# print file in STDOUT (optional)
$ cat /share/example.txt

No passphrase prompt

If you want to use the encryption/decryption without prompt, for example in a bash script, you can use the following options. Depending on the version, it can come to a distinction. Option 1 is by default not available in the Docker containers.

# symmetric encryption (option 1)
$ gpg -c --pinentry-mode=loopback --passphrase "PASSWORD" /share/example.txt && rm -f /share/example.txt

# symmetric encryption (option 2)
$ echo "PASSWORD" | gpg -c --batch --passphrase-fd 0 /share/example.txt && rm -f /share/example.txt

# symmetric encryption (option 3)
$ gpg -c --batch --passphrase "PASSWORD" /share/example.txt && rm -f /share/example.txt

# symmetric decryption (option 1)
$ gpg -d --pinentry-mode=loopback --passphrase "PASSWORD" -o /share/example.txt /share/example.txt.gpg && rm -f /share/example.txt.gpg

# symmetric decryption (option 2)
$ echo "PASSWORD" | gpg -d --batch --passphrase-fd 0 -o /share/example.txt /share/example.txt.gpg && rm -f /share/example.txt.gpg

# symmetric decryption (option 3)
$ gpg -d --batch --passphrase "PASSWORD" -o /share/example.txt /share/example.txt.gpg && rm -f /share/example.txt.gpg

Multiple files

You can also use a simple loop to encrypt/decrypt multiple files. Please note the available GPG version/options. Here now a simple example without prompt.

# create 3 text files from single file
$ split -l 1 -d /share/example.txt -a 1 --additional-suffix=".txt" /share/demo_

# check directory (optional)
$ ls -la /share/

# start symmetric encryption with multiple file
$ for file in /share/demo_{0..2}.txt; do gpg -c --batch --passphrase "PASSWORD" "$file" && rm -f "$file"; done

# check directory (optional)
$ ls -la /share/

# start symmetric decryption with multiple file
$ for file in /share/demo_{0..2}.txt.gpg; do gpg -d --batch --passphrase "PASSWORD" -o "${file::-4}" "$file" && rm -f "$file"; done

# check directory (optional)
$ ls -la /share/

Encryption and Decryption via keys

Container (user_a)

# generate keys
$ gpg --gen-key
...
kind of key: 1
keysize: 2048
valid: 0
Real name: user_a
Email address: user_a@demo.tld
...

# list keys (optional)
$ gpg --list-keys

# export public key
$ gpg --armor --export user_a@demo.tld > /share/user_a.asc

Container (user_b)

# generate keys
$ gpg --gen-key
...
kind of key: 1
keysize: 2048
valid: 0
Real name: user_b
Email address: user_b@demo.tld
...

# list keys (optional)
$ gpg --list-keys

# export public key
$ gpg --armor --export user_b@demo.tld > /share/user_b.asc

Both public keys are available.

# show folder content (optional)
ls -la /share/
...
-rw-r--r-- 1 root root  156 Oct 19 12:19 example.txt
-rw-r--r-- 1 root root 1707 Oct 19 13:22 user_a.asc
-rw-r--r-- 1 root root 1707 Oct 19 13:27 user_b.asc
...

Both clients need to import the public key from other.

# user_a
$ gpg --import /share/user_b.asc

# user_b
$ gpg --import /share/user_a.asc

# list keys (optional)
$ gpg --list-keys

Our user_a now encrypt data.

# encryption for recipient
$ gpg -e -r user_b /share/example.txt && rm -f /share/example.txt

# show folder content (optional)
$ ls -la /share/

User_b now decrypt data.

# decryption
$ gpg -d -o /share/example.txt /share/example.txt.gpg && rm -f /share/example.txt.gpg

# print file in STDOUT (optional)
$ cat /share/example.txt

I hope that you have found an entry point into the topic and I have woken up your interest.