Using GPG to encrypt raw data from a Perl Script

Ton Sistos antonio@moonlight.com
Tue Feb 27 19:33:08 2001


Thanks to everyone for their responses to my earlier post.  I suppose I
should have mentioned that I had already gone to CPAN before troubling
y'all...

There are three GPG modules on CPAN that I tried: GPG, GnuPG, and
Crypt::GPG.

GPG is not really Windows friendly, primarily because of its assumption of
Unix-like filepaths.  Once I edited it to work on my Win2K system, it
resulted in the same "hang forever" error as I previously listed. (This is
not really a surprise; the implementation is pretty much the same as the
code fragment I had earlier posted, except I used open2 instead of open3.)

GnuPG writes data to a file before calling the GPG program.  I'm trying to
avoid the I/O inefficiency penalty.

Crypt::GPG won't even compile on my system.  It requires (actually, 'use's)
Expect, which in turn requires IO::Pty.  I was unable to find a Windows
version of IO::Pty, probably because Windows can't _do_ pseudo tty (anyone
know otherwise?).

Which means I have to write the code myself.  With some help, I hope.  :)

I have since given up on using symmetric encryption for this program; the
asymmetric version seems almost as fast, and it saves me from having to pipe
in two input streams.  The code fragment is now:

use IPC::Open2;
sub Encrypt($$)
{
    my $data = shift;
    my $user = shift;
    my @result;
    my $pid;

    if (eval { $pid = open2(*README, *WRITEME, "gpg --quiet --recipient
$user --encrypt"); }) {
        binmode(README);
        binmode(WRITEME);
        print WRITEME $data;
        close WRITEME;
        @result = <README>;
        close README;
    }else die "Crud.\n";
    wait();
    return join("", @result);
}

This still hangs on the <README> call.  Incedentally, I tried running the
above command (gpg --quiet --recipient $user --encrypt) from the shell.  The
only way I could get GPG to stop reading from STDIN was to send it a Ctrl-Z
character on a line by itself.  (The program then returns the data exactly
the way I want it.)  I have tried to emulate this within my perl script by
sending every SIG my system understands (with "foreach (keys %SIG) { kill
$_, $pid; }" ) to the process without success.  I also tried printing every
ASCII character on a line by itself (since Ctrl-Z could also be ASCII 26);
this also failed.  Any ideas on how this could work?

Please cc me on any replies, as I am not on the mailing list.

Thanks!

Antonio (Ton) Sistos