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.

Tutorial: Encrypt, Decrypt, Sign a file with GPG Public Key in Linux

 

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).

 

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 the keyring that holds your secret keys
  • The pubring.gpg file is the keyring that holds your holds public keys.

The following steps shows Deepak creating a key pair for himself.

[root@node1 ~]# gpg --gen-key
gpg (GnuPG) 2.0.22; Copyright (C) 2013 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.

gpg: directory `/root/.gnupg' created
gpg: new configuration file `/root/.gnupg/gpg.conf' created
gpg: WARNING: options in `/root/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/root/.gnupg/secring.gpg' created
gpg: keyring `/root/.gnupg/pubring.gpg' created

The first question is about which kind of encryption (“what kind of key”) you want to use. The default, RSA and RSA, is a good choice.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection? 1

The next question concerns the size of the key. Larger keys are more secure but take longer to process. A key that is 2,048 bits long is a good compromise.

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 2048
Requested keysize is 2048 bits

Your answer to the next question determines when or if the key will expire. For most uses, a key that does not expire is a good choice. You must confirm this choice by typing y.

Please specify how long the key should be valid.
         0 = key does not expire
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 0
Key does not expire at all
Is this correct? (y/N) y

Next 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).

GnuPG needs to construct a user ID to identify your key.

Real name: Deepak Prasad
Email address: deepak.prasad@test.com
Comment: Deepak Prasad's Inbox
You selected this USER-ID:
    "Deepak Prasad (Deepak Prasad's Inbox) <deepak.prasad@test.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O

The last 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.

You need a Passphrase to protect your secret key.
            lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk
            x Enter passphrase                                    x
            x                                                     x
            x                                                     x
            x Passphrase ******__________________________________ x
            x                                                     x
            x                                                     x
            mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj

            lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk
            x Please re-enter this passphrase                     x
            x                                                     x
            x Passphrase ******__________________________________ x
            x                                                     x
            x                                                     x
            mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj

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: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key 20B43A0C marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
pub   2048R/20B43A0C 2018-12-09
      Key fingerprint = FBC3 2F86 D80D 977D 040D  F252 56BE E2ED 20B4 3A0C
uid                  Deepak Prasad (Deepak Prasad's Inbox) <deepak.prasad@test.com>
sub   2048R/3832437D 2018-12-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 (20B43A0C in the example) and the key 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
/root/.gnupg/pubring.gpg
------------------------
pub   2048R/20B43A0C 2018-12-09
uid                  Deepak Prasad (Deepak Prasad's Inbox) <deepak.prasad@test.com>
sub   2048R/3832437D 2018-12-09

[root@node1 ~]# gpg --fingerprint
/root/.gnupg/pubring.gpg
------------------------
pub   2048R/20B43A0C 2018-12-09
      Key fingerprint = FBC3 2F86 D80D 977D 040D  F252 56BE E2ED 20B4 3A0C
uid                  Deepak Prasad (Deepak Prasad's Inbox) <deepak.prasad@test.com>
sub   2048R/3832437D 2018-12-09

 

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-----
Version: GnuPG v2.0.22 (GNU/Linux)

mQENBFwNHRQBCAC0W1wyPH/d8H/2j55V3isHxIOg7jBlqZ2AUNZtH2errDSQWKEX
jgx7jA80Gn+/GpLMqga44Yhivb4hLiuys4J5tLid+9KOjJK4R67XB9iowW4XpkXm
HOpevLvW5O+pZlqBVOeswR8YUKb4DXqXsr8ebhvtI1xHvHeTUxWfH0ZJh3e4NtA7
X6PieG8u/2+Sl6yzcsAtj3MLyHIa8HJDnS8Nn49AJAWt8Is2Ln5ZMUpHGISlbWkS
PLWhwP2WwATFZ/0vtLG+lBlJkJ/UrmEXAuu56QBMYzMMxTWk1wnfpQweQC+1AcgN
..
AQABiQEfBBgBAgAJBQJcDR0UAhsMAAoJEFa+4u0gtDoMZiUH/2m0zTrauSCjHgC8
lx5W4hFzmgYnfAyJHyWj9A8lRvz6RlzZnjnvol76JJoALqvPKcgnsWiqkvybnqoZ
uR5FwDtPqDiyxAKCSAtVGAlRp5AD7pdclEh7vw/oGAT7vuq/TocesGFDWFqjyFrq
3bfYNNI0L5X0iE37AE6Kv7gQMsbfpwiUONz4zLDTexl+Ft6qGmu0bdSU5sTtt5Pm
VxDtZDdoCWBXCrEHrzUkv74RqXfYK5m+/Tj/Bbt6hHLH6in9Z4Zvh4c4wbGFNg8t
1maOnDOpB57jvax/oMhRFp7NR7H84NTmi+jqJR0882H4YmNpWwv3ndyFzP4w9xm3
0EFKdf8=
=bzPI
-----END PGP PUBLIC KEY BLOCK-----

Next Deepak sends the exported public key using scp to Amit.

After Amit receive Deepak’s public key, he adds it to his keyring using the following command

[root@node2 ~]# gpg --import deepak_pgp.asc
gpg: key 20B43A0C: public key "Deepak Prasad (Deepak Prasad's Inbox) <deepak.prasad@test.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
IMPORTANT NOTE:
Next, Deepak follows the same procedure to add Amit’s public key to his 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.gpg
------------------------
pub   2048R/20B43A0C 2018-12-09
uid                  Deepak Prasad (Deepak Prasad's Inbox) <deepak.prasad@test.com>
sub   2048R/3832437D 2018-12-09

pub   2048R/613099BE 2018-12-09
uid                  Amit Kumar (Amit Kumar's Inbox) <amit.kumar@test.com>
sub   2048R/B8AE9FEB 2018-12-09
[root@node2 ~]# gpg --list-keys
/root/.gnupg/pubring.gpg
------------------------
pub   2048R/613099BE 2018-12-09
uid                  Amit Kumar (Amit Kumar's Inbox) <amit.kumar@test.com>
sub   2048R/B8AE9FEB 2018-12-09

pub   2048R/20B43A0C 2018-12-09
uid                  Deepak Prasad (Deepak Prasad's Inbox) <deepak.prasad@test.com>
sub   2048R/3832437D 2018-12-09

 

Signing a Public Key

If you trust that a public key belongs to the person it says it belongs to, you can sign that key to make it more trustworthy. The more people who sign a key, the more trustworthy it becomes.

A key ID identifies a key. You can use the gpg --list-key option to list the IDs of all the keys on your keyring. The following output shows that Deepak’s key is 2,048 bits long, uses RSA encryption (R), and has a key ID of 613099BE on node1.

[root@node1 ~]# gpg --sign-key 613099BE

pub  2048R/613099BE  created: 2018-12-09  expires: never       usage: SC
                     trust: unknown       validity: unknown
sub  2048R/B8AE9FEB  created: 2018-12-09  expires: never       usage: E
[ unknown] (1). Amit Kumar (Amit Kumar's Inbox) <amit.kumar@test.com>


pub  2048R/613099BE  created: 2018-12-09  expires: never       usage: SC
                     trust: unknown       validity: unknown
 Primary key fingerprint: 8D09 5E6D 57BF 81AF D356  3190 FD29 32DC 6130 99BE

     Amit Kumar (Amit Kumar's Inbox) <amit.kumar@test.com>

Are you sure that you want to sign this key with your
key "Deepak Prasad (Deepak Prasad's Inbox) <deepak.prasad@test.com>" (20B43A0C)

Really sign? (y/N) y

You need a passphrase to unlock the secret key for
user: "Deepak Prasad (Deepak Prasad's Inbox) <deepak.prasad@test.com>"
2048-bit RSA key, ID 20B43A0C, created 2018-12-09

The following output shows that Amit’s key is 2,048 bits long, uses RSA encryption (R), and has a key ID of 20B43A0C on node2.

[root@node2 ~]# gpg --sign-key 20B43A0C

pub  2048R/20B43A0C  created: 2018-12-09  expires: never       usage: SC
                     trust: unknown       validity: unknown
sub  2048R/3832437D  created: 2018-12-09  expires: never       usage: E
[ unknown] (1). Deepak Prasad (Deepak Prasad's Inbox) <deepak.prasad@test.com>


pub  2048R/20B43A0C  created: 2018-12-09  expires: never       usage: SC
                     trust: unknown       validity: unknown
 Primary key fingerprint: FBC3 2F86 D80D 977D 040D  F252 56BE E2ED 20B4 3A0C

     Deepak Prasad (Deepak Prasad's Inbox) <deepak.prasad@test.com>

Are you sure that you want to sign this key with your
key "Amit Kumar (Amit Kumar's Inbox) <amit.kumar@test.com>" (613099BE)

Really sign? (y/N) y

You need a passphrase to unlock the secret key for
user: "Amit Kumar (Amit Kumar's Inbox) <amit.kumar@test.com>"
2048-bit RSA key, ID 613099BE, created 2018-12-09

 

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 her private key; no one else can read the file.

I have a secret file on node1

[root@node1 ~]# cat secret
This is a secret file

Following, Amit encrypts the secret file using Deepak’s public key, yielding an unreadable file named secret.gpg.

[root@node1 ~]# gpg --recipient deepak.prasad@test.com --encrypt secret
gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
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

Then sends the file to Amit on node2

[root@node1 ~]# scp secret.gpg node2:~/
root@node2's password:
secret.gpg

When Deepak receives the file, he decrypts it using his secret key:

[root@node2 ~]# gpg --output secret --decrypt secret.gpg

You need a passphrase to unlock the secret key for
user: "Amit Kumar (Amit Kumar's Inbox) <amit.kumar@test.com>"
2048-bit RSA key, ID B8AE9FEB, created 2018-12-09 (main key ID 613099BE)

gpg: encrypted with 2048-bit RSA key, ID B8AE9FEB, created 2018-12-09
      "Amit Kumar (Amit Kumar's Inbox) <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

 

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.

 

References:

A practical Guide to Fedora and Red Hat Enterprise Linux

1 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *