CGI and Perl

Simplified PGP Transactions Using the PGP Module

In the simplest case, you may wish to implement an encrypted transaction simply and quickly, but not necessarily through the browser or server. For instance, when I wanted to subscribe to "The Perl Journal," I was asked to encrypt my credit card number using the PGP public key for TPJ, then mail the encrypted credit-card number to them. What then? In this case, there is again a Perl module available specifically for this purpose. It's called the PGP module, and it provides a nice Perlish interface to the PGP binary, available for noncommercial users from MIT and commercial entities through ViaCrypt. (We're not going to get into the details of what PGP is, or how it works, here. For that information, you can consult the "Applied Cryptography" text mentioned at the end of the chapter, along with the documentation that comes with PGP itself.)

The PGP module provides the user with a number of convenient methods, once the base PGP object has been created with the new method, as usual. The following is a listing of the most important methods:

Sign Take a file or scalar variable and sign it with the user's secret key.
Encrypt Produce and encrypt a file or variable from an unencrypted variable or file using a public key(s).
Decrypt Decrypt a file or text variable by using a secret key.
Keyring::new Produce an object that has elements corresponding to each key on a user's keyring. This object is then useful for checking the completeness and trust level of any given key.
Keyring::Add_Key Add a new key to the user's keyring.
Keyring::Remove_Key Remove a key from a user's keyring.

We'll be using the 0.3 Version of the PGP module for the following example. Note that the PGP module is still somewhat in a state of flux but is stable enough for simple projects. The author, as is common to all module authors, is amenable to bug fixes or appropriate changes. The latest version can be obtained from the CPAN. (I had to apply some fixes to the 0.3 version to get it to work. The fixed version is available in the sample code area on the CD-ROM.)

Now suppose, as was previously mentioned, that we wanted to encrypt a simple document and mail it to someone by using that person's public key to encrypt the document, to be sure that only that person could then read it. Naturally, you could use the PGP binary directly. We won't get into that, because the PGP module provides much more flexibility. The following script will prompt you for the receiver's public key and your secret key in order to encrypt a file. Then it will mail the encrypted file off to the receiver, prompting for his/her e-mail address or using his/her public key as the default mail address.

 # simple script to send pgp encrypted mail -
 use PGP::Pipe;
 use Mail::Send;
 $pgp = new PGP::Pipe;
 # get the users pgp password, echo off
 print("Type your PGP Password (echo disabled) :\n");
 system("stty -echo");
 chop($PGP_Password = <STDIN>);
 system("stty echo");
 # get the public keys for the recipients
 print "Now enter the user ID(s) to encrypt with: ";
 chop($TO_id = <STDIN>);
 # use the public key(s) as the email address by default
 print "Send the mail to: [$TO_id] ";
 chop($To = <STDIN>);
 ($To = $TO_id) unless (length($To));
 # Get a subject line
 print "Enter the subject : ";
 chop($Subject = <STDIN>);
 # prompt for the filename to send
 print "Enter the file to send : ";
 chop($file = <STDIN>);
 # create the encrypted document and stuff into a variable
 $encrypted =  $pgp->Encrypt(Password => $PGP_Password, File => $file,  TO_id => $TO_id, Clear => 1, Armor => 1);
 # Create new Mail::Send object, using the address specified
 $mail = new Mail::Send Subject => $Subject, To => $To;
 # print the encrypted message on the mail body, and send.
 $fh = $mail->open;
 print $fh $encrypted;

Pretty simple, eh? We used the Mail::Send module to deliver the message here, which won't be formally introduced until Chapter 7, but you get the idea. Encryption really isn't a deep, dark secret known only to the wizards. Anyone can use it, and Perl makes it even easier. Client Security The client-side of the Web transaction has analogies to some of the preceding potential problems, as well. The client may need to be assured that the server it is receiving its data from is who it says it is (spoofing), and that the data itself is truly what was sent from the server. Additionally, the client may be asked to execute some code, in the form of a Java applet, Java script, TCL script, or Perl script (discussed in Chapter 15), or some other "Helper Application."

In general, it's not recommended to enable the embedded scripting features within a given browser if you have secure or proprietary data anywhere within access of the user running the browser. Further, it's risky to enable certain helper applications to automatically read or run spreadsheets or other word-processor documents. It's a known fact that such documents may contain macros that can cause viruses to infect your system.

It's always safer to save a given document, script, or whatever to disk by default, then (minimally) run some virus-detection software against it and visually inspect it, if it's text, before assuming it's safe. Even then, if you are extremely cautious, assume that it may contain a virus or Trojan horse that hasn't even been discovered yet.


Always use the latest updates of any virus detection software you run. This probably goes without saying, but new viruses are always in the process of being implemented, then discovered, and then dealt with in any particular virus-detection software.