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