In my last article I shared the steps to improve Disk IO Performance in Linux. Security is a major part of the foundation of any system that is not totally cut off from other machines and users. In this article I will guide you with the steps to secure your critical data before transferring the file to your client. You can encrypt a file using signed GPG key before you transfer or send the file to the recipient. Once the file is received by the client, they can further decrypt the file before viewing the content. This way you can be assured that you secret file is not targeted by any hacker to steal the data.
What is encryption?
One of the building blocks of security isencryption,which provides a means of scrambling data for secure transmission to other parties. In cryptographic terms, the data or message to be encrypted is referred to asplaintext,and the resulting encrypted block of text asciphertext.Processes exist for converting plaintext into ciphertext through the use ofkeys,which are essentially random numbers of a specified length used tolockandunlockdata. This conversion is achieved by applying the keys to the plaintext according to a set of mathematical instructions, referred to as theencryption algorithm.
How GPG encrypt and decrypt works?
GPG uses public key encryption wherein you create a key pair: one private or secret key you keep to yourself and one public key you share with your correspondents or the world. The important part of this two-key system is that neither key can be calculated by having the other. They are each an independent and necessary part of the system and are based upon solid mathematical foundations.
This setup allows you to
- Use your private key to sign a document to provide identification and message integrity to a recipient who has your public key.
- Identification means the recipient can be certain the document came from you.
- Message integrity means the recipient knows the message has not been altered.
- You can provide these features because only you have your private key.
- Use the recipient’s public key to encrypt a document and provide secrecy.
- Secrecy means that only the recipient (who has the corresponding private key) can decrypt the document.
- Combine these steps to provide identification, message integrity, and secrecy (i.e., only the recipient can decrypt the document, the recipient knows the document came from you, and the recipient knows the document was not altered).
Step 1: Creating a GPG Key Pair
To start working with GPG you need to create a key pair for yourself.
- Use gpg with the
--gen-keyoption to create a key pair. - With this option, gpg creates and populates the
~/.gnupgdirectory if it does not exist. - The
secring.gpgfile is thekeyringthat holds your secret keys - The
pubring.gpgfile is thekeyringthat holds your holds public keys.
I am creating the key for user Deepak. Here you specify your real name (you can specify a nickname or handle in the comment section), your email address (the one most people associate with you), and an optional comment. After you specify these traits, a prompt allows you to edit them, quit, or continue (Okay).
[root@node1 ~]# gpg --gen-key
gpg (GnuPG) 2.2.9; Copyright (C) 2018 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Note: Use "gpg --full-generate-key" for a full featured key generation dialog.
GnuPG needs to construct a user ID to identify your key.
Real name: Deepak Prasad
Email address: deepak.prasad@test.com
You selected this USER-ID:
"Deepak Prasad <deepak.prasad@test.com>"
Change (N)ame, (E)mail, or (O)kay/(Q)uit? O
At the next step in generating a key pair is specifying a passphrase that will keep your secret key secure. The passphrase should have the Deepak characteristics as a password except it should be longer. Protect the passphrase as you would a password.
┌──────────────────────────────────────────────────────┐
│ Please re-enter this passphrase │
│ │
│ Passphrase: ________________________________________ │
│ │
│ <OK> <Cancel> │
└──────────────────────────────────────────────────────┘
After you enter a passphrase, gpg generates your keys. Generating truly random keys requires many random bytes, and generating random bytes requires entropy. As the instructions suggest, type on the keyboard, move the mouse, and use the disk (e.g., copy several large files) to gain entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key 2234BC88364829B7 marked as ultimately trusted
gpg: revocation certificate stored as '/root/.gnupg/openpgp-revocs.d/A469D9E3D1AF4A79DA9D437E2234BC88364829B7.rev'
public and secret key created and signed.
pub rsa2048 2021-02-09 [SC] [expires: 2023-02-09]
A469D9E3D1AF4A79DA9D437E2234BC88364829B7
uid Deepak Prasad <deepak.prasad@test.com>
sub rsa2048 2021-02-09 [E] [expires: 2023-02-09]
When gpg finishes, you have generated your key pair. The gpg utility
stores all information in the ~/.gpg directory. Your keys, and public
keys you import using gpg, are stored on your keyring. The output shows
two items you will use while working with gpg: the key ID
(A469D9E3D1AF4A79DA9D437E2234BC88364829B7 in the example) and the
key fingerprint.
Step 2: List the key pair and fingerprint
After you have generated your key pair, you can display information
about the pair using the gpg --list-keys and --fingerprint options.
A fingerprint is a shorthand for the public portion of a key; you can
use it for manual identification of the key.
[root@node1 ~]# gpg --list-keys
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2023-02-09
/root/.gnupg/pubring.kbx
------------------------
pub rsa2048 2021-02-09 [SC] [expires: 2023-02-09]
A469D9E3D1AF4A79DA9D437E2234BC88364829B7
uid [ultimate] Deepak Prasad <deepak.prasad@test.com>
sub rsa2048 2021-02-09 [E] [expires: 2023-02-09]
[root@node1 ~]# gpg --fingerprint
/root/.gnupg/pubring.kbx
------------------------
pub rsa2048 2021-02-09 [SC] [expires: 2023-02-09]
A469 D9E3 D1AF 4A79 DA9D 437E 2234 BC88 3648 29B7
uid [ultimate] Deepak Prasad <deepak.prasad@test.com>
sub rsa2048 2021-02-09 [E] [expires: 2023-02-09]
Step 3: Exporting and Importing Public Keys
Next you need to export your public key and then share the public key to
your recipient. The following command exports public keys (--export)
in ASCII format (--armor; or -a) to a file named deepak_pgp.asc
(--output; or -o followed by the name of the file you want to write
to). If you specify a user, the command exports the public key for that
user, otherwise it exports the public keys for all users on the public
keyring.
Following, Deepak writes his public key to deepak_pgp.asc and then displays that file.
[root@node1 ~]# gpg --export --armor --output deepak_pgp.asc deepak.prasad@test.com
[root@node1 ~]# cat deepak_pgp.asc
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBGAiYsEBCADICHRr6g2xkOOCmON5riLywyf+03zD4AEHyPXhVRi8mhoCqbLh
EQiaciUM97uvvPHV12/oncYct2MF7HUzSK2izGbJlpaBhNQ/BIwFoQPC4lI4D9PP
aeL12ABG838D9qhjtvRorv/rQJ2s+xDk5nTj1vFadhs32cQAkFu8iHRQeEvAc/cE
GJt6xjeykE0k/0QjH7Ockp1ernvWgU107dy3vH52lxwrhKAG3J42mx5iLQ0g/N9O
TLTIJEUBVfhB0hi3w58WeIZf7sT6f7e5p68eY9IW6SvE9DF6EyAdieAwDjYbrIAx
LYWkXXYyFE5uNdU9muV4BPkDbU7yq6rnSMnTABEBAAG0JkRlZXBhayBQcmFzYWQg
PGRlZXBhay5wcmFzYWRAdGVzdC5jb20+iQFUBBMBCAA+FiEEpGnZ49GvSnnanUN+
IjS8iDZIKbcFAmAiYsECGwMFCQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AA
CgkQIjS8iDZIKbcBjgf/fsqVTTOc1FKBS/0z44yemHVFh2rJIGSlc619l2tKAyK5
P53oIL/fBWRfnZatF/kUuIvQTXoxLiRnHHXCeuhtv5UlcNP1hwdwWkVQj8pgSiGc
88PBcV/FIIcPt6wkJuislv3+pMNJyWBwH/w5O00bnwPKXS4TlKTDcD/7NWBV7vxv
ctz4QvYD6bAEz6J48RHQrE6mIAwRodP1hOV8IKhEoc46YG0Mp6iDKmgYR5arVBX1
Os3cKvSFI/LO3Sm7edBhq1riDUUfMuJicP1/+Ak4CBB+wD+1luCQ9ydhNHwRv9if
NNwMOzSzSbofNjKEoZDiAaBV0aCUVsNZgwFqj7Z7sLkBDQRgImLBAQgA3P1V0C8X
eZiFWiPKsqoJ269ntYbxeUdpCM2k8IHUENQIetexakCWB2CuDmGQbmV3JzHVOIla
rKEUeMkvMt21SU91O7XWRbw3KPi/tYfBM54D1nVsqf0Z90A4DtIysWKetXnxlp2w
GcZXoD5w/1kMrBw76rh8YHhQwqVwLNrp/HvFBl/d0nKfk5/axDGkTp6yVIAH3iv7
/Y+3hSygKg7JQwGgDifzHqD1FC5hNxeKf30dCs36JU9LBtYdG8O9bhsSWQ0m73+W
gp7PtJvFsEOedH2Sn4eeGdTCsFuM1psv2+NH1D2ZeHaXaM81SnDXuBQt4m10r91C
/pIg5Ct3YGSWiwARAQABiQE8BBgBCAAmFiEEpGnZ49GvSnnanUN+IjS8iDZIKbcF
AmAiYsECGwwFCQPCZwAACgkQIjS8iDZIKbfyBwf+P0SOKs7WclpbWjcYEwT/8QAi
BjP37mV2p6fLZUzo1YUJA1UeO6zcnTKoBPwhIZLxD8E/QRwIgoDGpeS2TsCrIcIM
m5v2QYdx4qoy8LOKiD9Qniy2Y/PoipJsNZD/ZTevxzkchtMIsWMUylVF7vxmp+an
2jCxvRHJPIqvVu3T9yW+4FALSt2FfHbM0JtkQWUlR1LfFe5nGMGT/rbnUMRDOzL5
EaxXmUQoLAicMPKwRsLJ9edi4FjmLfG1wZQHg81MVhJGvzbbYAlGMP4r5NL27Zzc
7C+n9SaC9vnBE2V/dZXArMXSuA3dr/11mjHak37JanmCGdTq+6D80PRhS3gAIA==
=mnAk
-----END PGP PUBLIC KEY BLOCK-----
Next Deepak sends the exported public key using scp to user Amit on node2.
[root@node1 ~]# scp deepak_pgp.asc node2:/root/
root@192.168.43.48's password:
deepak_pgp.asc 100% 1769 1.1MB/s 00:00
After user Amit receives Deepak’s public key, he adds it to his
keyring using the following command:
[root@node2 ~]# gpg --import deepak_pgp.asc
gpg: key 2234BC88364829B7: public key "Deepak Prasad <deepak.prasad@test.com>" imported
gpg: Total number processed: 1
gpg: imported: 1
keyring. The following examples assume Deepak and Amit
have each other’s public keys on their keyrings.
Below is the list of keys on node1 (Deepak) and node2(Amit) after repeating the above procedure on node2 for Amit
[root@node1 ~]# gpg --list-keys
/root/.gnupg/pubring.kbx
------------------------
pub rsa2048 2021-02-09 [SC] [expires: 2023-02-09]
A469D9E3D1AF4A79DA9D437E2234BC88364829B7
uid [ultimate] Deepak Prasad <deepak.prasad@test.com>
sub rsa2048 2021-02-09 [E] [expires: 2023-02-09]
pub rsa2048 2021-02-09 [SC] [expires: 2023-02-09]
002A69050935012C8B617459E9B5780906DCCFB8
uid [ unknown] Amit Kumar <amit.kumar@test.com>
sub rsa2048 2021-02-09 [E] [expires: 2023-02-09]
[root@node2 ~]# gpg --list-keys
/root/.gnupg/pubring.kbx
------------------------
pub rsa2048 2021-02-09 [SC] [expires: 2023-02-09]
A469D9E3D1AF4A79DA9D437E2234BC88364829B7
uid [ unknown] Deepak Prasad <deepak.prasad@test.com>
sub rsa2048 2021-02-09 [E] [expires: 2023-02-09]
pub rsa2048 2021-02-09 [SC] [expires: 2023-02-09]
002A69050935012C8B617459E9B5780906DCCFB8
uid [ultimate] Amit Kumar <amit.kumar@test.com>
sub rsa2048 2021-02-09 [E] [expires: 2023-02-09]
Step 4: Signing a Public Key
If you want to keep a file from prying eyes and ensure that it comes from the person it says it comes from and that it has not be altered, you can sign the file using your private key and encrypt it using the recipient’s public key. The recipient can then decrypt it using his public key and verify the signature using the sender’s public key.
[root@node1 ~]# gpg --sign-key 002A69050935012C8B617459E9B5780906DCCFB8
pub rsa2048/E9B5780906DCCFB8
created: 2021-02-09 expires: 2023-02-09 usage: SC
trust: unknown validity: unknown
sub rsa2048/CEEBD939AE75371A
created: 2021-02-09 expires: 2023-02-09 usage: E
[ unknown] (1). Amit Kumar <amit.kumar@test.com>
pub rsa2048/E9B5780906DCCFB8
created: 2021-02-09 expires: 2023-02-09 usage: SC
trust: unknown validity: unknown
Primary key fingerprint: 002A 6905 0935 012C 8B61 7459 E9B5 7809 06DC CFB8
Amit Kumar <amit.kumar@test.com>
This key is due to expire on 2023-02-09.
Are you sure that you want to sign this key with your
key "Deepak Prasad <deepak.prasad@test.com>" (2234BC88364829B7)
Really sign? (y/N) y
┌────────────────────────────────────────────────────────────────┐
│ Please enter the passphrase to unlock the OpenPGP secret key: │
│ "Deepak Prasad <deepak.prasad@test.com>" │
│ 2048-bit RSA key, ID 2234BC88364829B7, │
│ created 2021-02-09. │
│ │
│ │
│ Passphrase: __________________________________________________ │
│ │
│ <OK> <Cancel> │
└────────────────────────────────────────────────────────────────┘
Similarly we will sign Deepak’s key on node2.
[root@node2 ~]# gpg --sign-key A469D9E3D1AF4A79DA9D437E2234BC88364829B7
pub rsa2048/2234BC88364829B7
created: 2021-02-09 expires: 2023-02-09 usage: SC
trust: unknown validity: unknown
sub rsa2048/505BF17C9A4A329D
created: 2021-02-09 expires: 2023-02-09 usage: E
[ unknown] (1). Deepak Prasad <deepak.prasad@test.com>
pub rsa2048/2234BC88364829B7
created: 2021-02-09 expires: 2023-02-09 usage: SC
trust: unknown validity: unknown
Primary key fingerprint: A469 D9E3 D1AF 4A79 DA9D 437E 2234 BC88 3648 29B7
Deepak Prasad <deepak.prasad@test.com>
This key is due to expire on 2023-02-09.
Are you sure that you want to sign this key with your
key "Amit Kumar <amit.kumar@test.com>" (E9B5780906DCCFB8)
Really sign? (y/N) y
┌────────────────────────────────────────────────────────────────┐
│ Please enter the passphrase to unlock the OpenPGP secret key: │
│ "Amit Kumar <amit.kumar@test.com>" │
│ 2048-bit RSA key, ID E9B5780906DCCFB8, │
│ created 2021-02-09. │
│ │
│ │
│ Passphrase: __________________________________________________ │
│ │
│ <OK> <Cancel> │
└────────────────────────────────────────────────────────────────┘
Step 5: Encrypting and Decrypting a File
When you encrypt a file using a public key, only the corresponding private key can decrypt the file. If you want to send a file to someone such that only that person can read (or run) that file, you can encrypt the file using the recipient’s public key. Then the recipient can decrypt the file using his private key and no one else can read the file.
I have a secret file on node1
[root@node1 ~]# cat secret
This is a secret file
Here I want to make sure this file is read by user Amit only. So, we
will encrypt the secret file using Amit’s public key, yielding an
unreadable file named secret.gpg.
[root@node1 ~]# gpg --recipient amit.kumar@test.com --encrypt secret
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 1 trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: depth: 1 valid: 1 signed: 0 trust: 1-, 0q, 0n, 0m, 0f, 0u
gpg: next trustdb check due at 2023-02-09
Verify the encrypted file:
[root@node1 ~]# ls -l secret.gpg
-rw-r--r--. 1 root root 354 Feb 9 16:19 secret.gpg
As you can see this is an encrypted file:
[root@node1 ~]# file secret.gpg
secret.gpg: PGP RSA encrypted session key - keyid: 39D9EBCE 1A3775AE RSA (Encrypt or Sign) 2048b .
So now we can safely send this over to node2 where we expect user Amit to be able to read this file only.
[root@node1 ~]# scp secret.gpg node2:~/
root@node2's password:
secret.gpg 100% 354 578.9KB/s 00:00
When Amit receives the file, he decrypts it using his secret key which is already available in the keyring:
[root@node2 ~]# # gpg --output secret --decrypt secret.gpg
gpg: encrypted with 2048-bit RSA key, ID CEEBD939AE75371A, created 2021-02-09
"Amit Kumar <amit.kumar@test.com>"
Next an decrypted file is created 'secret', now Amit can view the
content of the file
[root@node2 ~]# cat secret
This is a secret file
Deleting public keys from keyring
Assuming you don’t need the secret keys any more and wish to delete it, first we should list if there are any secret keys available for the respective user:
~]# gpg --list-secret-keys
/root/.gnupg/pubring.kbx
------------------------
sec rsa2048 2021-02-09 [SC] [expires: 2023-02-09]
A469D9E3D1AF4A79DA9D437E2234BC88364829B7
uid [ultimate] Deepak Prasad <deepak.prasad@test.com>
ssb rsa2048 2021-02-09 [E] [expires: 2023-02-09]
Since I wish to delete Deepak’s key pair so first I will delete his secret key:
~]# gpg --batch --delete-secret-keys --yes A469D9E3D1AF4A79DA9D437E2234BC88364829B7
Make sure the secret key is deleted properly:
~]# gpg --list-secret-keys
Next we will delete Deepak’s public key:
~]# gpg --list-keys
/root/.gnupg/pubring.kbx
------------------------
pub rsa2048 2021-02-09 [SC] [expires: 2023-02-09]
A469D9E3D1AF4A79DA9D437E2234BC88364829B7
uid [ultimate] Deepak Prasad <deepak.prasad@test.com>
sub rsa2048 2021-02-09 [E] [expires: 2023-02-09]
pub rsa2048 2021-02-09 [SC] [expires: 2023-02-09]
002A69050935012C8B617459E9B5780906DCCFB8
uid [ full ] Amit Kumar <amit.kumar@test.com>
sub rsa2048 2021-02-09 [E] [expires: 2023-02-09]
So let’s delete Deepak’s key:
~]# gpg --batch --delete-keys --yes A469D9E3D1AF4A79DA9D437E2234BC88364829B7
Verify the available keys:
~]# gpg --list-keys
gpg: checking the trustdb
gpg: no ultimately trusted keys found
/root/.gnupg/pubring.kbx
------------------------
pub rsa2048 2021-02-09 [SC] [expires: 2023-02-09]
002A69050935012C8B617459E9B5780906DCCFB8
uid [ unknown] Amit Kumar <amit.kumar@test.com>
sub rsa2048 2021-02-09 [E] [expires: 2023-02-09]
Conclusion
There are some advantages of using GPG:
- It uses strong, hard-to-crack encryption algorithms.
- It uses the private/public key scheme, which eliminates the need to transfer a password to a message or file recipient in a secure manner. Instead, just send along your public key, which is useless to anyone other than the intended recipient.
- You can use GPG to just encrypt your own files for your own use, the same as you’d use any other encryption utility.
But it also has some disadvantages
- Using public keys instead of passwords is great when you work directly only with people who you implicitly trust. But for anything beyond that, such as distributing a public key to the general population so that everyone can verify your signed messages, you’re dependent upon a web-of-trust model that can be very hard to set up.
- For the end-to-end encryption of email, the recipients of your email must also have GPG set up on their systems and know how to use it. That might work in a corporate environment, but lots of luck getting your friends to set that up. (I’ve never once succeeded in getting someone else to set up email encryption.)Lastly I hope the steps from the article to encrypt, decrypt, sign a file with GPG public key on Linux was helpful. So, let me know your suggestions and feedback using the comment section.


