GPG-GNU Privacy Guard Tutorial (Commandline Encryption and Decryption)
Communication through internet is always exposed to security risks of some or the other kind. Any message transmission done through TCP or UDP can always be intercepted with simple packet capturing tools to read the content inside.
Many people are of the opinion that messages between two parties cannot be be intercepted without getting into the middle of their communication path. Although that is true till a certain extent, there are other things to consider where security is the main concern. Let's consider some cases where a possible security breach can happen.
- What if the receiver's machine is compromised and an attacker has access to the data .
- What if you by mistake, send the message to somebody other than the intended receiver.
- How will you verify the reply that you are getting is unaltered.
- What if an ISP that comes in between the sender and receiver is compromised and an attacker can intercept messages.
In this tutorial we will be discussing GPG (GNU Privacy Guard), a very reliable method that can be used to encrypt,decrypt, and also authenticate data and messages send and received.
GPG is open source, and is licensed with GPL(General Public License). There are two types of encryption that can be used. One is symmetric encryption and the other is asymmetric encryption. In symmetric encryption the same key is used to encrypt and decrypt, Which means both the sender and receiver must have the same key. For symmetric encryption to work, the symmetric key(which will be used by both parties, and are used for encryption and decryption) must be shared .
That poses another security risk. How will you share that symmetric key, because if an attacker gets that key, then the encryption is of no use. To solve this problem, asymmetric encryption was introduced(Public Key Cryptography). In asymmetric encryption Each and every user has two keys. Once is the public key and the other is the private key.
If you want to send some encrypted data to a receiver in asymmetric encryption, then you need to have the public key of the receiver. And if the receiver has to send back some encrypted message to you, then he must have your public key. So the two parties engaging in communication must have each other's public key with them.
Anything encrypted with the public key can only be decrypted with the corresponding private key(Which is kept securely and not shared at all.). Hence if you send some encrypted message to a receiver, with the help of his public key, then he only can open/decrypt that message, because he only has the corresponding private key. So the public key is shared to all those who can send messages to you, and you need to have the public key of theirs if you want to send encrypted messages to them. The most interesting part of public key is that, even the sender cannot decrypt the message once he has encrypted it with the receiver's public key(Only the receiver can decrypt it with his private key.). Hence keys are always made as key pair.
A public key is always constructed in relation to a private key. Let's see how this works in GPG.
You need to have a package called gnupg in Linux to work with gpg. Most of the Linux distributions have this installed by default. I will be showing this example tutorial with gnupg on Red Hat Systems.
[root@myvm1 ~]# rpm -qa | grep gnupg gnupg-1.4.5-14 [root@myvm1 ~]#
To secure the communication with the help of GPG, you need to first create a key pair. Its quite simple to create the key pair, but what's important to understand here is the fact that, which algorithm's are being used and what are the differences among them. We at slashroot, believe more in concepts than commands. Commands can be easily found by looking at the man pages or the documentation paper's, however concepts and to understand how things work requires an extensive research, and at times need to digg deeper to find that out.
Let's create our key pair with the help of --gen-key argument in gpg command.
[root@myvm1 ~]# gpg --gen-key gpg (GnuPG) 1.4.5; Copyright (C) 2006 Free Software Foundation, Inc. This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. See the file COPYING for details. Please select what kind of key you want: (1) DSA and Elgamal (default) (2) DSA (sign only) (5) RSA (sign only) Your selection?
Now let's understand each and every option in the output. The --gen-key parameter provides you three options to select form. They each have thier own differences.
(1) DSA and Elgamal (default)
This is the first option that you get while generating key pair in gpg. And its shown in there, that its the default option that will be selected. Which means if you just press enter during the selection, it will by default select the first option of DSA and Elgamal. Default key pair depends on the version of gnupg you are using, so it might vary from the example shown above, if you are using a different version of gnupg.
This first option will create two key pairs. One DSA key pair and one Elgamal key pair. Here we need to understand something, before going ahead. DSA is only used for Digital Signatures.
Digital signature can be used to check two things.
- To verify the sender
- To verify the message and confirm that it has not been changed/altered.
A digital signature can be made with the help of a private key, and a signature can be verified by the corresponding public key. Normally the whole message/data, the sender is sending is never signed, because signing a whole message will increase the overhead.
A better alternative to signing the whole message, is to sign the cryptographic hash of the message/data.
Note: A cryptographic hash function is used to verify the integrity of the data, and to check that data was not altered. The main plus point of using cryptographic hash function is that, a hash will always be unique to a particular data. Altering any character in the data will produce a different hash.
There are a number of hash algorithms that are being used. Among them DSA signing algorithm uses the SHA1 (and sometimes SHA2 due to security concerns involved in SHA1)
The major plus point of a digital signature like DSA is that, nobody can forge the signature of anybody because that requires the private key. But yeah, anyone with the public key can verify the data that's signed.
Hence selecting this first option of DSA and Elgamal will generate two key rings. One for encryption(Elgamal), and the other for Digital Signature(DSA).
(2)DSA (sign only)
This second option will create only one key pair. This will be only used for Digital signature. So if you select the second option, you will be able to sign your documents before sending but you will be unable to encrypt it using gpg(Because this option does not create a public/private key for encryption. This will only create a publc/private key for Digital Signature.)
Hence if you select this option, gpg will inform you that encryption cannot be done with this key pair, as a final message after the key creation. The message looks something like the below.
Note that this key cannot be used for encryption. You may want to use the command "--edit-key" to generate a subkey for this purpose.
(3)RSA (sign only)
This third option will do the same thing, of generating keys for digital signature, by using another encryption algorithm called as RSA. Similar to the second option, you will not be able to encrypt data if you select this option, but will be able to sign your documents before sending.
This option will create only one key pair, similar to the DSA (Sign Only) option. Hence you will get a similar exact same message after creating your signing keys with this option.
Note that this key cannot be used for encryption. You may want to use the command "--edit-key" to generate a subkey for this purpose.
Some facts about RSA, DSA, and Elgamal in GNUPG
- DSA stands for Digital Signature algorithm, and is only used for signing the documents and not encrypting it.
- DSA is based on a mathematical problem called as Discrete Logarithmic Problem(Which is difficult and time consuming for even powerful computer's to solve)
- RSA algorithm can also be used for encrypting as well as digital signature's
- Signature size of DSA is small compared to large signature's generated by RSA algorithm.
- RSA works on a mathematical problem called as Integer Factorization Problem(Which also is difficult for computer's to solve).
- DSA defaults to 1024 key size in GPG
- You have a choice to select a key size for encryption using Elgamal algorthim ranging from 1024 to 4096 bits
- The private key is the major component for decrypting and signing messages, which means you need to secure your private key with encryption and password protection, which is done bydefault by the GPG
- Setting an expiry date for your private key is advisable, because it adds a little bit more security.
Let's now generate our key pair by selecting the first option to understand the steps. Here we will be selecting the first option because we need to both encrypt as well as sign our data/message with the help of DSA algorithms.
[root@myvm1 ~]# gpg --gen-key gpg (GnuPG) 1.4.5; Copyright (C) 2006 Free Software Foundation, Inc. This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. See the file COPYING for details. Please select what kind of key you want: (1) DSA and Elgamal (default) (2) DSA (sign only) (5) RSA (sign only) Your selection? 1 DSA keypair will have 1024 bits. ELG-E keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) Requested keysize is 2048 bits Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n years Key is valid for? (0) Key does not expire at all Is this correct? (y/N) y You need a user ID to identify your key; the software constructs the user ID from the Real Name, Comment and Email Address in this form: "Heinrich Heine (Der Dichter) <email@example.com>" Real name: Name must be at least 5 characters long Real name: Slashroot Email address: firstname.lastname@example.org Comment: Slashroot Key You selected this USER-ID: "Slashroot (Slashroot Key) <email@example.com>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o You need a Passphrase to protect your secret key. 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 195C8BDB 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 1024D/195C8BDB 2013-04-26 Key fingerprint = 5C77 CEE6 10B9 5E1C 1B0D B2E1 BB1D E5D8 195C 8BDB uid Slashroot (Slashroot Key) <firstname.lastname@example.org> sub 2048g/8BCCF604 2013-04-26
In the above shown example of gpg --gen-key command, we have already discussed the first selection option for DSA & Elgamal,DSA,RSA.
The second question asked by gpg is to specify the bit size for Elgamal key(Which will be used for encryption of data.). Its a widely accepted belief that if you use long size key's, then it will be difficult for a brute force to happen on that easily. However successful attack's against encryption key's happens due to human carelessness or some other social engineering means.
Although longer key's provide some immunity towards brute force attacks, they themselves becomes a performance bottleneck while encrypting and decrypting data.
To understand how key size matter's we need to think in terms of combinations and number of attempts that an attacker needs to carry out to do a successful break. 128 bit key means an attacker has to try 2 128 combinations. And a key size of 1024 means an attacker has to go through 21024 Combinations to do find the right match.
Selecting the default 1024 will be fine here.
The next option is to specify number of days, after which the private key will expire. Most people ignore this, and press an enter, in order to select the default "0" option which will not make the key expire.
The next option will ask you to provide some identity information which will uniquely identify this key. Information asked will be email,Name,and a comment. Later on , you can select any of the information to identify the key which you want. This is very useful because you will be able to manage multiple keys, and can use the required key with the help of one single identify information you supplied.
The final asked by gpg is to supply a password that will be used to protect your private key with encrypted security. If you want to use this private key, for encryption, you will be prompted for a password.
Encryption, Importing & Exporting Keys, Signing and verifying example's in gnupg
We already have created key pairs for encryption/decryption & Digital Signatures. Now let's go through some real world example's to understand how this whole thing works.
Let's first understand how digital signature in gnupg works, with some example signature creation.
A digital signature is made with the help of a private key, and can be verified with the help of the corresponding public key. This is possible because public key will be distributed to all your recipients, by email or through website. A digital signature will not encrypt the data, but will add a signature with the hash value of the data, that you want to sign. The receiver can then verify the signature with the help of GPG or any other such application software.
Let's first create some message and sign it, so that the receiver can verify that its send by you. Suppose i have a message that's initially written in simple text format.
[root@myvm1 ~]# cat example-message hello this is a test message to verify gpg signature. This message is from slashroot.in team, hence it is signed with our private key, which you can verify with our public key. [root@myvm1 ~]#
Now let's sign that message with gpg.
[root@myvm1 ~]# gpg --local-user "Slashroot" --clearsign "example-message" You need a passphrase to unlock the secret key for user: "Slashroot (Slashroot Key) <email@example.com>" 1024-bit DSA key, ID 195C8BDB, created 2013-04-26
In the above example method shown we have used the "Realname" argument we submitted while generating our key pair(In our case it was "Slashroot"). If you have a look at man pages for gpg, you will come to know that --clearsign, argument is used to make a signature of clear text format, which can be viewed with the help of any text editor.
Signing the message will prompt you for a password, this is the password that you have used to encrypt the private key. As private key is the one, which you are using to sign a message, you need to give the password.
Now as we have signed our message let's see how our signature looks like. After signing the text message, you will get a file with the extension of .asc, which will contain both the message and the signature. Let's see our example-message.asc file that contains the digital signature.
[root@myvm1 ~]# cat example-message.asc -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 hello this is a test message to verify gpg signature. This message is from slashroot.in team, hence it is signed with our private key, which you can verify with our public key. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.5 (GNU/Linux) iD8DBQFRe2R1ux3l2Blci9sRAtd8AKCM6sN4Xg3aWLyOAiUza5HurxUU8gCfVlbw wxI9ZZ2VnCY88SBR/e/xkfo= =vBz9 -----END PGP SIGNATURE----- [root@myvm1 ~]#
The output clearly mentions that, the hash of the message, which we signed is using SHA1.
Now as i mentioned earlier, the people who need to verify your signed messages will require your public key. For that you need to publish you public key and make it available to your recipients. This can be done by either sending to your preferred recipient through email, or you can also make it available for download in your website. But for this, you first need to export your public key in simple text format, so that other's can use it. Lets see how.
[root@myvm1 ~]# gpg --armor --output "slashroot-public-key" --export "Slashroot"
In the above shown example, we have exported our public key to a file called "slashroot-public-key", which can be now made available to the recipients. In the above shown commands we have used --armor option with gpg command, to specify that the output must be in plain text format. And --export argument requires the identity of the key, which is again the Realname that we have used while generating the key pair(You can also use the email address provided while creating the keyring). Let's now see the content of our public key.
[root@myvm1 ~]# cat slashroot-public-key -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.5 (GNU/Linux) mQGiBFF6nikRBACEHpnImkcocXCigGgG9CqJYJTXT+X/3Ky1nLgXmhJf1O/Lk7pA mfO0TdPC4A/RkKZf0jHm1kkIl4EE02t4c+/qts1z1LOxDoHTDjx+xpfRpC2ekKq5 2+LtSXaFRlbTPVsi4cSEBDOGUpyAFOYAjtKI1c+q90Ru1g7ViXduXtbVfwCgpFxV ZbFAmTpK47xKcqnpwwWv9ysD/j3w34vS7sywgAuflVecYeYa1xGM1XLPfZDMJKJO AxwuJBrsx6GX3jKh6ah1MlnbxB1+rqzWqKa+qeVHGTegQV89GcC1ut06EcJamd4l k2LG2MdkvKVoQBGQIj+VglP24Q9KfhhBd7mheqzLsQh2i5YtW6TTszvG/i283V6R lSAMA/4r9lpwTL1Fgsgb8794PkaxKL6JwRgRWoIwCikRKB9W2Ot+/nK0y2nfZcpX 5jzw0R40jE+AMItL25ulRPpqHVD9CHxBPgOH0lwTg3Tk5KcFsgn1pxch+3K/TuDM OXJN64V35AIEayUHNIT+42Hym1xalX1vGZMO+x7F5/wrUyNGIrQuU2xhc2hyb290 IChTbGFzaHJvb3QgS2V5KSA8YWRtaW5Ac2xhc2hyb290LmluPohgBBMRAgAgBQJR ep4pAhsDBgsJCAcDAgQVAggDBBYCAwECHgECF4AACgkQux3l2Blci9s6fACfVsbb J8xNQ8DMB3eJl1QVFypTaGgAmgNA/Gnh0UwR83GVezWkBGmqmI6BuQINBFF6njUQ CAChBVGhNI5lKcQ0le94ABom5RTu2bCPnE0E5jijauANBGqvocae93yTUAu98Mdy r3587m8Zpx1Pv2FH/PSGs3cHWcugCJcH9yfxiXRy9rCvQu8NYFdwVFrInNpgt4nT 7JPUDYEqpvYLBfjxpbPCrbcUGr9ZwFm2sNjIiZBhWzm9bzcEIp9JxwxWoHSXc0rD AxZMfdUY1OvGNjfpbIewNm2QhJ0CwvSX4j0FoSpkbx0Axnmuf/W+CXgI3VJir9hd RRgGpligi11xQsOhWtBSesLDP7ooecsIRPr6cTlQz73FErY5u+P6xmyxfuKT4Hfx xFFoP9DGNpoJFhbOkJCvhxpjAAMFCACWLKq+O2PnXY29jS8gf3LhLD62agSKuw3f GxhRx3M1ZWcwsG05IrXaS1YUZ1JlFmxgF3nSzZc11mbZHxJB+2IDje93MlwT9Kw5 7h8f2khGAXg1qg43Amel11WdfptWd+ULBxM4iPTC1xub4PAP/iUF2L/c7vFlvCIZ gAkgY8dXC+ElNKV56vKCLl3+5REvjK6NI38wC104ONdPTemyPK+wRNBrTSNS6+ao BOrKoNGEveeU0sDo1H59hp3k5m+JvNdW1IMfj2VVxzaNGmm+BbdbUUShEZDlkbTo bNuKEUfGTmuepJFwWzxrEeBkrxlhFnyJTF2vw0F1oEZgmHnOmDq1iEkEGBECAAkF AlF6njUCGwwACgkQux3l2Blci9vMSACfWDx1EshJtDLh3zD3IaZ+xEyGAfwAnjD9 sS7kecpFm5niggNSyjzD2+KK =fc8Y -----END PGP PUBLIC KEY BLOCK----- [root@myvm1 ~]#
Any recipient who has this public key can import it to his list of public key's to verify our signed messages in future. Lets see how to import this public key.
[sarath@myvm1 ~]$ gpg --import slashroot-public-key gpg: keyring `/home/sarath/.gnupg/secring.gpg' created gpg: key 195C8BDB: public key "Slashroot (Slashroot Key) <firstname.lastname@example.org>" imported gpg: Total number processed: 1 gpg: imported: 1 [sarath@myvm1 ~]$
--import option in gpg takes the public key you want to import, as an argument, and will have the exact identity of the real name, and email address etc. You can also use this same key identify for verifying signature's as well as encrypting messages.
Let's see how to verify the message with this public key we just imported. Here for showing this example, we will be verifying our previously signed message example-message.asc.
But before we verify any message with the newly imported key, we need to set a trust level on that key. Otherwise gpg will show you warning messages like the below.
gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner.
For setting a trust level on a public key, we need to use the argument --edit-key.
[sarath@myvm1 ~]$ gpg --edit-key "Slashroot" gpg (GnuPG) 1.4.5; Copyright (C) 2006 Free Software Foundation, Inc. This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. See the file COPYING for details. pub 1024D/195C8BDB created: 2013-04-26 expires: never usage: SC trust: unknown validity: unknown sub 2048g/8BCCF604 created: 2013-04-26 expires: never usage: E [ unknown] (1). Slashroot (Slashroot Key) <email@example.com> Command> trust
--edit-key argument with gpg command gives you a prompt, in which you can assign trust level to that public key. In the gpg edit prompt, you need to enter the command trust to assign a trust level to that public key. You will be presented with 5 different level's of trust, from which we will be selecting the level 5 inorder to completely trust the key.
1 = I don't know or won't say 2 = I do NOT trust 3 = I trust marginally 4 = I trust fully 5 = I trust ultimately m = back to the main menu
After selecting the trust level, you can exit this key edit prompt by typing "quit". Let's now finally verify the signature with the help of this trusted public key which we have imported.
[sarath@myvm1 ~]$ gpg --verify example-message.asc gpg: Signature made Fri 26 Apr 2013 10:39:01 PM PDT using DSA key ID 195C8BDB gpg: Good signature from "Slashroot (Slashroot Key) <firstname.lastname@example.org>" [sarath@myvm1 ~]$
Let's finally send some encrypted messages with the help of slashroot public key we have imported, and then will try decrypting it with the help of the recipient's private key.
For encrypting the message's with the help of gpg, you need to privide two command line arguments. One argument will specify the public key to use(This is done with the argument --recipient, because data will be encrypted with the recipient's public key.), and the other argument will take the file which will be encrypted using this public key.
To encrypt messages to slashroot, we will be using Slashroot public key, which we have already imported.
[sarath@myvm1 ~]$ gpg --recipient "Slashroot" --output "sample-message.gpg" --encrypt "sample-message"
Now send this output file to the recipient by any method. On recieving the message (sample-message.gpg), the reciever can easily decrypt it, with his private key to view the content inside.
Again this will require the recipient to type in the password, for his private key, because private key is used to decrypt this message.
[root@myvm1 ~]# gpg --decrypt "sample-message.gpg" You need a passphrase to unlock the secret key for user: "Slashroot (Slashroot Key) <email@example.com>" 2048-bit ELG-E key, ID 8BCCF604, created 2013-04-26 (main key ID 195C8BDB) gpg: encrypted with 2048-bit ELG-E key, ID 8BCCF604, created 2013-04-26 "Slashroot (Slashroot Key) <firstname.lastname@example.org>" hello this a sample message to test gpg encryption.
How to send an encrypted email message with gpg by using plain text?
In the above shown method of sending encrypted data to the reciever, we need to send the entire file. The main reason was because the encrypted file was in binary format.
What if you want to send a complete email message as a simple text, but still encrypted. For this, we need to use the same --armor option, we earlier used while exporting or making public keys available as plain text.
So the first step is to type the entire email message in a text editor. Lets go through this example email message.
[sarath@myvm1 ~]$ cat sample-email Hi, This is a test email message to test encryption.. Thanks & regards [sarath@myvm1 ~]$
Now encrypt this entire email message with the recipient's public key, which in our case is "Slashroot".
[sarath@myvm1 ~]$ gpg --armor --recipient "Slashroot" --output "sample-email.asc" --encrypt "sample-email" [sarath@myvm1 ~]$
The next step is to simply copy paste the content of "sample-email.asc", to the email message body(From any of your email clients like thunderbird,outlook, or even gmail etc.)
The reciever can simply copy paste the email content to a text file and decrypt it to read the message, by the following method.
[root@myvm1 ~]# gpg --decrypt "sample-email.asc" You need a passphrase to unlock the secret key for user: "Slashroot (Slashroot Key) <email@example.com>" 2048-bit ELG-E key, ID 8BCCF604, created 2013-04-26 (main key ID 195C8BDB) gpg: encrypted with 2048-bit ELG-E key, ID 8BCCF604, created 2013-04-26 "Slashroot (Slashroot Key) <firstname.lastname@example.org>" Hi, This is a test email message to test encryption.. Thanks & regards [root@myvm1 ~]#
Again the reciever will be prompted for the password for his private key. In the above shown example, we have assumed that the reciever has saved the email content to a file called "sample-email.asc". The file name with which the reciever saves the content, does not matter at all. But yeah the entire content without mistake must be available.