Digital Developer Conference: Cloud Security 2021 – Build the skills to secure your cloud and data Register free

Archived | Using Open PGP to encrypt or decrypt files based on keys

Archived content

Archive date: 2019-08-11

This content is no longer being updated or maintained. The content is provided “as is.” Given the rapid evolution of technology, some content, steps, or illustrations may have changed.


GnuPG, or gpg, is the free implementation of the well known Open PGP project. It allows you to encrypt or decrypt files based on keys. gpg uses what is commonly known as the public key cryptography, using a private and public key to allow safe encryption or decryption of files.

How gpg works

The private and public keys are required to offer security of files when transferring over unsecured networks. The private key is owned by the generator of the keys (which the owner should only have access to), and the other key is a public key (which can be distributed to anyone). The distribution list depends on what application you are using gpg for, and of course, the distribution list of users must have gpg installed as well.

The private key is for owners only and is further secured by a passphrase by the owner. The public key can be freely distributed or exchanged with other gpg users. Once you have been sent a public key from another user (or you may have downloaded it from a web site), you need to add it to your public keyring. This file holds all your public keys. You need this to encrypt files (assuming you are sending files to other users) using the intended recipients public key. They can then decrypt your encrypted file using their own private key.

In this article, I will demonstrate how to generate a pair of keys, as well as encrypting and decrypting files. Decrypting and encrypting can be used purely for ones own security, you do not have to share your public key if you are not exchanging files with other trusted users. I will also demonstrate how to sign a file and how to check the integrity of the contents. I will also demonstrate how to use gpg within a batch environment.

Installing gpg

The current version of gpg is 2.0.16 and can be built from source. I have only been successful building it from source using a commercial C compiler. Since this is not an option for most administrators, I am using a pre-compiled binary gpg version 1.4.7 for this demonstration. Details of downloads can be found in the Related topics section.

$ gpg
gpg: Go ahead and type your message ...

You may get a warning about insecure memory similar to the following:

$ gpg
gpg: WARNING: using insecure memory!
gpg: please see for more information
gpg: Go ahead and type your message ...

To get rid of this warning, make the gpg binary set uid:

chmod 4755 gpg

Generating your key pair

Before you can begin to encrypt or decrypt files, your first task is to generate your public and private key using the gen-key option of gpg. Listing 1 is a truncated output of the command. You will be asked questions about the type of key, size, and how long should the key life should be. For this demonstration, I have answered those questions provided below:

Key: DSA and Elgamal
Key size:  2048
Never expire the key
Name: David Tansley
Comment: aix admin
Passphrase: watchmaker

For clarity I have used my full name in the key generation during this demonstration, but the name can be any alias that identifies you. I could have used dxtans, for example.

Note: Keep your passphrase secure, do not forget it, as you will be prompted for it when using gpg operations on files.

Listing 1. generate keys

$gpg --gen-key
gpg (GnuPG) 1.4.7; Copyright (C) 2006 Free Software Foundation, Inc.
gpg: please see for more information
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
Real name: david tansley
Email address:
Comment: aix admin
You selected this USER-ID:
    "david tansley (aix admin) <>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
You need a Passphrase to protect your secret key:watchmaker
gpg: /home/dxtans/.gnupg/trustdb.gpg: trustdb created
gpg: key DD096620 marked as ultimately trusted
public and secret key created and signed.
uid                  david tansley (aix admin) <>
sub   2048g/25B15F46 2010-08-10

Once the keys have been created, a subdirectory will be present in your HOME directory called .gnupg . This directory will be the holding place for your public and private keys, as well as your public keyring. You will need public keys from users who send you their encrypted files, so you can decrypt them.

Now the keys have been generated, lets encrypt a file, then decrypt it.

Encrypting and decrypting a file for personal usage

The format to use gpg to encrypt files for personal usage is:

gpg <options> <filename>

Practically all options given to gpg are prefixed by two dashes, like so: – –

Encrypting a file for personal usage does not require the encrypt option. To encrypt a text file, specify the armour that creates a shield around the text. By default, gpg will assume it is a binary file you wish to encrypt. The symmetric option informs gpg to use a passphrase. Lastly, the name of the input file is parsed. In this case, it is the file-name myfile. Once the command is issued, you will be prompted to enter your passphrase. This phrase is the same one entered when the keys were generated. Notice we do not have to specify the type of cipher; by default gpg will use CAST5.

$ cat my_file
Meet me at the same place tonight, come alone

$ gpg --armour --symmetric my_file
enter passphrase:

gpg will generate a new file with an extension of .asc, containing the encrypted information:

$ ls -l my_file*
-rw-r--r--    1 dxtans   staff            46 Aug 12 19:37 my_file
-rw-r--r--    1 dxtans   staff           211 Aug 12 19:37 my_file.asc

Looking at the now encrypted file, it is now unreadable:

$ cat my_file.asc
Version: GnuPG v1.4.7 (AIX)


You can also specify the name of the encrypted file to be produced using the output option. In the following example, the encrypted file will be called myoutfile:

gpg --armour --output myoutfile --symmetric my_file

To decrypt the file just created, use the decrypt option specifying the name of the encrypted file. The format to use gpg to decrypt files is:

gpg <options> --decrypt <file-name>

The file will be displayed to standard output:

$ gpg --decrypt my_file.asc
gpg: CAST5 encrypted data
gpg: encrypted with 1 passphrase
Meet me at the same place tonight, come alone
gpg: WARNING: message was not integrity protected

To specify the output of the decrypted file, use the output option. In the following example the decrypted file will be called my_decrypt_file:

gpg --output my_decrypt_file --decrypt outfile

The following will achieve the same as the above example but this time using file redirection:

gpg --decrypt my_file.asc >my_decrypt_file

To disable gpg informational messages, use the quiet option when decrypting:

$ gpg --decrypt --quiet my_file.asc
Meet me at the same place tonight, come alone
gpg: WARNING: message was not integrity protected

Even after using the quiet option you may still get a warning about not being integrity checked. The warning is caused if the original file was not encrypted with modification detection checking enabled. This warning can be suppressed by issuing the no-mdc-warning when decrypting a file:

gpg --decrypt --no-mdc-warning --quiet my_file.asc

As a general rule, it is best not to have the warning at all rather then suppressing it. To encrypt a file forcing an mdc, use the option force-mdc:

gpg --force-mdc --armour --output outfile --symmetric myfile

Exporting and importing keys

When files are to be exchanged, the file is first encrypted using the intended recipients public key. Once the recipient gets the encrypted file, the recipient uses his own private key to decrypt the file. Typically, this public key can be uploaded onto a trusted site where uses can then download it and put it into their keyring. However, when using gpg within an enterprise business environment, and you are exchanging sensitive files, the users you give your public key to will be very selective. Accordingly, to receive encrypted files from other users, you will need their public key to unlock their file for you to read it; their public key will go into your keying.

Once your public key is exported, you can then transfer the key to its destination either by email, scp or ftp. The format to use gpg to export the public key is:

gpg --armour --output < file-name> --export <key-name>

Where key-name is the real name you entered when generating your keys. Notice I am exporting with the armour option, as the key will be exported in ASCII mode.

To view your keys, you can list your current key keyring using the list-keys option:

$ gpg --list-keys
pub   1024D/DD096620 2010-08-10
uid                  david tansley (aix admin) <>
sub   2048g/25B15F46 2010-08-10

In the above example for the UID, I could use either david tansley or, as both names identify me. In this scenario, I will use:

You can also list your private key with:

$ gpg --list-secret-keys
sec   1024D/DD096620 2010-08-10
uid                  david tansley (aix admin) <>
ssb   2048g/25B15F46 2010-08-10

To export my public key in ASCII mode to the file dxtans_pubkey:

$  gpg --armor --output dxtans_pubkey --export david tansley
$  ls -l dxtans_pubkey
-rw-r--r--    1 dxtans   staff          1180 Aug 14 08:34 dxtans_pubkey

Alternatively, I could use redirection to produce the output file, like so:

gpg --armor --export david tansley > dxtans_pubkey

Listing 2 . public key. Shows a truncated output of my public key

$ cat  dxtans_pubkey
Version: GnuPG v1.4.7 (AIX)


The next task is to send my public key to user(s) that I want to send encrypted files to, so that they can decrypt the files using their own private key. In this demonstration, I am going to send my public key via email to the company security officer (busintel). That person’s fictitious email address is

The key can now be transferred via ftp, scp, or just pipe the export command into an email. In the following example, my public key is exported, and the contents are piped into the email content with the subject line of pubkey:

$ gpg --armour --export | mail -s pubkey

Alternatively, I could send it as an attachment file called dxtans_pubkey.txt in a email:

mail -s " intel.. Here is my public key" $list <<mayday

~<!uuencode dxtans_pubkey dxtans_pubkey.txt

Now the key has been sent, user busintel can now download the file to import it into his keyring. The format of the command to import a key is:

gpg --import <filename>

User busintel would now perform the following to import my public key, assume he saves my public key as dxtans_pubkey:

$ gpg --import dxtans_pubkey
gpg: key DD096620: public key "david tansley (aix admin) <>"
gpg: Total number processed: 1
gpg:               imported: 1

To confirm the public key is now in busintel’s key ring, user busintel could list his keys, like so:

$ whoami
$  gpg --list-keys
pub   1024D/2326BEEA 2010-08-11
uid                  busintel  (company intel) <>
sub   2048g/8DCD62BC 2010-08-11

pub   1024D/DD096620 2010-08-10
uid                  david tansley (aix admin) <>
sub   2048g/25B15F46 2010-08-10

Giving trust

When decrypting files, gpg will ask if this person is who he says he is. You can inform gpg of your trust level in the person’s public key you hold by informing gpg of your trust level. The format of the command is:

gpg --edit-key <UID>

Listing 3 demonstrates how you can inform gpg of the trust for each public key you have in your keyring. When presented with the prompt, enter the keyword trust. Next, select from the menu your level of trust. In the following example, is having his trust raised by user busintel to the level of ultimate trust.

Listing 3. Giving trust

$ gpg --edit-key
gpg (GnuPG) 1.4.7; Copyright (C) 2006 Free Software Foundation, Inc.
pub  1024D/2326BEEA  created: 2010-08-11  expires: never       usage: SC
                     trust: unknown       validity: unknown
sub  2048g/8DCD62BC  created: 2010-08-11  expires: never       usage: E
[ unknown] (1). busintel  (company intel) <>
import key:
Command> trust
pub  1024D/2326BEEA  created: 2010-08-11  expires: never       usage: SC
                     trust: unknown       validity: unknown
sub  2048g/8DCD62BC  created: 2010-08-11  expires: never       usage: E
[ unknown] (1). busintel (company intel) <>
Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)
  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
Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y

pub  1024D/2326BEEA  created: 2010-08-11  expires: never       usage: SC
                     trust: ultimate      validity: unknown
sub  2048g/8DCD62BC  created: 2010-08-11  expires: never       usage: E
Command> quit

The trust setting has now been changed to ultimate trust for david tansley’s public key.

I would now perform the same process to import busintel’s public key into my keyring. Let’s now assume that has been completed. We are now ready to exchange encrypted files.

Encrypting and decrypting files using public keys

Let’s assume I have just completed some MIS statistics contained in a spreadsheet. I now need to send user busintel this sensitive file. The command format to encrypt a file with a public key is:

gpg <options> --encrypt --recipient(s) <uid of person(s) sending to> <filename>

The file name to encrypt is monthly_mis.xls. The file name will be output as 2010_08_mis.xls. The recipient’s name is busintel.

As this file is not ASCII, I will not use the armor option. The following command will encrypt the file, using the information provided above, using busintel’s public key:

$ gpg  --output 2010_08_mis.xls --encrypt --recipient 'busintel' monthly_mis.xls
$ ls 2010*
$ cat 2010_08_mis.xls
Version: GnuPG v1.4.7 (AIX)


The file 2010_mix.xls is now sent via email to busintel for that user to decrypt.

The command format to decrypt a file with a public key is:

gpg <options> --decrypt <filename >

The user busintel has now received the file and will now decrypt it; this is carried out using his own private key. The user busintel has decided to call the decrypted file aug_mix. He will be prompted for his own passphrase (in this example, it is called papercutter) to complete the decryption process.

User busintel would run the following command to decrypt which is in the previous encrypt example. I had encrypted the file using busintel’s public key; he can now decrypt using his own private key:

$ gpg --output aug_mis --decrypt 2010_08_mis.xls
You need a passphrase to unlock the secret key for
user: "busintel (business intel) <>"
2048-bit ELG-E key, ID F96A3FD7, created 2010-08-14 (main key ID 86C597BF)
Enter passphrase:papercutter
gpg: encrypted with 2048-bit ELG-E key, ID F96A3FD7, created 2010-08-14
      "busintel (business intel) <>

The file has now been decrypted and is called aug_mix for user busintel to review.

Deleting keys

Over a period of time your keyring will become quite populated with keys, some keys will no doubt belong to users whom are no longer present within your key exchange. To delete these keys, use the delete-key option. The command format to delete a key is:

gpg --delete-key <UID>

Before running the above command, be sure to use the list-keys option to identify correctly the key before deletion. In the following example, the public key of bravo is deleted. Notice that I first list the keys to be sure of the correct UID I am using:

$ gpg --list-keys
pub   1024D/DD096620 2010-08-10
uid                  david tansley (aix admin) <>
sub   2048g/25B15F46 2010-08-10
pub   1024D/28B78F84 2010-08-14
uid                  bravo (aix user) <>
sub   2048g/860FAE6D 2010-08-14

$ gpg --delete-key bravo
gpg (GnuPG) 1.4.7; Copyright (C) 2006 Free Software Foundation, Inc.
pub  1024D/28B78F84 2010-08-14 bravo (aix user) <>
Delete this key from the keyring? (y/N) y

Going batch

Dealing with encryption or decryption within a batch environment means one thing: automation. The only human interaction that is required to encrypt or decrypt files depending on the process is entering of the passphrase. gpg offers the batch option, where the passphrase can be parsed or read into the passphrase prompt. There are a few ways this can be done. One could echo a string and pipe it through to gpg or redirect from a file or read from a file into gpg.

The command format to run in batch mode is:

gpg < options> -- batch --passphraseX <filename>

Where passphaseX is passphrase-fd n (file descriptor and number) and passphrase-file (filename).

Using the batch option along with passphrase-fd. The passphrase will be read in via the local file descriptor. The following command encrypts the text file myfile and outputs it to tord3.gpg. Notice the use of the batch option along with the passphrase-fd 3. Here we open file descriptor 3 and then read into that the file descriptor the file called .passf. The contents of .passf is the single passphrase contained on one line, with no line feeds and only readable by the owner.

$ cat .passf

$ gpg --armor --output tord3.gpg --batch --symmetric --passphrase-fd 3 3<.passf myfile

Still using the passphrase-fd example, we could also echo in a string containing the passphrase into the input stream fd 0, like so:

echo watchmaker | gpg --output tord3.gpg --batch --symmetric --passphrase-fd 0 myfile

Another example that is very similar to the above uses the batch option along with the passphrase-file. Here the file .passf containing the passphrase is read in by gpg.

gpg --armor --batch --symmetric --passphrase-file .passf --output tord3.gpg myfile

As in both examples, there is no user input required which makes it ideal for batch processing large volumes of files. The passphrase file containing the passphrase to use should only contain one passphrase and should not contain a line feed at the end of the line.

Listing 4 contains a script that will check the directory /opt/hfc/holding/ for files matching the pattern ‘mis*’ to encrypt. If found, it will encrypt these using the batch passphrase-file option. The file containing the passphrase is ./home/dxtans/.gnupg/.passf. The files are encrypted with user busintel’s public key in readiness for that user to decrypt them (whom also has my public key). The files, once encrypted are created in the /opt/hfc/encrypt directory.

Listing 4. encrypt_files

# encrypt_files



filelist=$(ls $input_dir/mis* 2>&1)
   if [ $? != 0 ]
    echo "no files to process...exiting"
    exit 0

  for txtfile in $filelist
  filename=$(basename $txtfile)

  echo "attempting to encrypt..$txtfile"
  gpg --batch --force-mdc --output $output_dir/$filename.gpg --armor --passphrase-file
    $passf --symmetric --encrypt --recipient 'busintel'  $txtfile
  if [ $? != 0 ]
    echo "Failed on $txtfile to encrypt to $output_dir/$filename.gpg"
    echo "OK $txtfile encrypted, new location  $output_dir/$filename.gpg"
   #  rm $txtfile

When the script is run, the output is similar to the following:

$ /home/dxtans/.gnupg/encrypt_files
attempting to encrypt../opt/hfc/holding/mis_341
OK /opt/hfc/holding/mis_341 encrypted, new location  /opt/hfc/encrypt/mis_341.gpg
attempting to encrypt../opt/hfc/holding/mis_342
OK /opt/hfc/holding/mis_342 encrypted, new location  /opt/hfc/encrypt/342.gpg

Once the files have been processed, it is just a matter of decrypting them using the batch option again with the passphrase-file. For example, user busintel could decrypt the file mis_341.gpg as he has the public key of the sender. The file will be decrypted to: /opt/hfc/encrypt/mis_341

$ gpg --batch --quiet --output /opt/hfc/encrypt/mis_341 --decrypt --passphrase-file
/home/bisintel/.gnupg/.passf  /opt/hfc/encrypt/mis_341.gpg

File integrity

There are cases where you will send text files to users, or perhaps a file you are uploading to a public area, where the file itself needs not be encrypted. But, the users need to be sure that the file has come from the actual person it says it has. One method to achieve this is to clearsign your file using your own private key. This does not encrypt your file , but rather creates another copy of the file, with the file extension of .asc. This new file contains your signature as well as the contents of the original file. You will be prompted for your passphrase when you sign the file.

To clear sign a file, the command format is:

gpg --clearsign < filename>

For example, to sign the file my popfile, I could use:

$ gpg --clearsign popfile
You need a passphrase to unlock the secret key for
user: "david tansley (aix admin) <>"
1024-bit DSA key, ID DD096620, created 2010-08-10

The above command will produce another file called popfile.asc. The signature can be verified by other users using the verify option:

$ gpg --verify popfile.asc
gpg: Signature made Sat Aug 14 16:59:03 BST 2010 using DSA key ID DD096620
gpg: Good signature from "david tansley (aix admin) <>"

If the file has been tampered with, you will get a bad signature message, like so:

$ gpg --verify popfile.asc
gpg: Signature made Sat Aug 14 16:59:03 BST 2010 using DSA key ID DD096620
gpg: BAD signature from "david tansley (aix admin) <

To sign binary files, use the command:

gpg --sign <filename>


GnuPG provides a secure method of encrypting your own personal files or files you exchange between users. In this article, I have demonstrated how gpg can be used to encrypt and decrypt files, also how gpg can be used within a batch environment.