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 is encryption, 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 as plaintext, and the resulting encrypted block of text as ciphertext. Processes exist for converting plaintext into ciphertext through the use of keys, which are essentially random numbers of a specified length used to lock and unlock data. This conversion is achieved by applying the keys to the plaintext according to a set of mathematical instructions, referred to as the encryption 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-key
option to create a key pair. - With this option, gpg creates and populates the
~/.gnupg
directory if it does not exist. - The
secring.gpg
file is thekeyring
that holds your secret keys - The
pubring.gpg
file is thekeyring
that 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.
I’m trying to decrypt pgp file in terminal by exporting public,secret keys from other server but when i’m decrypting file ,i’m getting error
Try killing the existing gpg-agent process. Here I could find some more proposed working solution for this error https://stackoverflow.com/questions/28321712/gpg-decryption-fails-with-no-secret-key-error
Can we perform this task with ansible ?
I am afraid have never tried.
All seem good now. Happy of being helpful. Thanks.
Thanks for reply.
You’re right, I made some research yesterday about signing a public key and i was able to well understand it.
About errors that i notify last, there remain some to correct.
At the beginning, it’s Amit who encrypt file by using Deepak public key by doing this:
The next step is to send the encrypted file to *Deepak*, but you said: “Then sends the file to Amit on node2”
After that, when Deepak receive the encrypted file, he should decrypt it by using *his private key*, but you use Amit private key to decrypt it as follow:
You agree with that, Deepak shouldn’t know Amit passphrase and also, if it’s he who is concern by decrypting file, he should use his private key.
Hope you pay attention to that and make appropriate corrections. Thanks.
Thanks for highlighting this, I guess I somehow mixed up the output during my trial runs and I don’t have the same setup to fix the output. So I have updated the entire article based on the output from my CentOS 8 environment. Please let me know if you still find any discrepancies.
Hi.
Thanks very much for this tutorial. It was of great help for me. But, first
For encryption and decryption section i think there was an error. See it by yourself in following lines. You say :
1- Following, Amit encrypts the secret file using Deepak’s public key, yielding an unreadable file named secret.gpg.
2- Then sends the file to Amit on node2
3- When Deepak receives the file, he decrypts it using his secret key:
4- Next an decrypted file is created ‘secret’, now Amit can view the content of the file
There is an inconsistency in this.
Apart from the fact that there is no point in encrypting the file to decipher it yourself, Amit cannot encrypts a file using Deepak’s public key and decrypts it using her private key: this is what has been done.
Second, i have a question. What is the use of signing public key ? I didn’t understand it here
Thanks for tutorial and hope my feedback will be useful.
Thanks Ansuim for the feedback. I have corrected “now Amit can view the content of the file” to “now Deepak can view the content of the file”
Regarding the second question: Signing a key tells your software that you trust the key that you have been provided with and that you have verified that it is associated with the person in question. This can help other people decide whether to trust that person too. If someone trusts you, and they see that you’ve signed this person’s key, they may be more likely to trust their identity too.
uping gpg command line i’m encrypting my file ( containing numeric data ) but when encrypted it is getting appended with Chinese character , how to file is in asci format
Do you mean in the encrypted file or after decrypt you see these characters?
Hi Admin,
I want to sign a file with one account (e.g., C1) but encrypt with other account (C2) public key so that I can decrypt it with C2. All I have to do with bash script. Any idea, please.
I feel this should be possible as long as the recipient which in this case C2 has both private and public key. I am not sure what you mean by doing all in bash script? You can definitely automate the commands but the script would vary depending upon your usecase.
I have followed your tutorial therefore both C1 and C2 has public and private key.
Here is the usecase. C1 will sign a document for example. Then we will encrypt it with C2’s public key (C2 has private key also and C2’s public key is in the keylist of C1 and also vice versa) so that C2 can decrypt it with his private key. For above usecase I need two scripts which will automate the process. Like in one hand one script will sign and encrypt it. Other hand, the other script will decrypt it. I hope this clears the situation.
This line is wrong – Deepak’s key is 2,048 bits long, uses RSA encryption (R), and has a key ID of 613099BE
This ID belongs to Amit.
pub 2048R/613099BE 2018-12-09
uid Amit Kumar (Amit Kumar’s Inbox)
sub 2048R/B8AE9FEB 2018-12-09
Thanks for marking the error, I have updated the text
Hi
Hi