http://www.perlmonks.org?node_id=964682


in reply to Perl GPG Chat

GnuPG::Tie::Encrypt from GNUPG, from the given example, would appear to be more what you might be looking for. It uses a tied file handle to interface with GnuPG, rather than requiring data to be written to a file to be encrypted.

Hope that helps.

Replies are listed 'Best First'.
Re^2: Perl GPG Chat
by riven (Novice) on Apr 12, 2012 at 05:23 UTC
    Thank you so much, that does exactly what I want! I'm much farther along now, and sending messages works fine. However, on the receiving end when I try to decrypt the message I get: protocol error: expected DECRYPTION_OKAY got PLAINTEXT

    I can't find where I've messed up, I tried to follow the example CPAN code as much as I could - but clearly I've done something wrong. I've marked the line near the very bottom where it appears to be erroring.

    #!/usr/bin/env perl use warnings; use strict; use Term::ReadKey; # For the noecho use GnuPG::Tie::Encrypt; use GnuPG::Tie::Decrypt; # Global vars here my $message_separator = "!"; # Separate messages on !, because gpg wil +l put newlines into the message, but never uses '!' in ascii-armor # End of global vars client( $ARGV[0], $ARGV[1] ) if( @ARGV == 2 ); daemon( $ARGV[0] ) if( @ARGV == 1 ); usage() if( @ARGV != 1 && @ARGV != 2 ); sub usage { print "Usage:\n"; print "$0 <port_number> # For listening as a daemon\n"; print "$0 <ip_address> <port_number> # For connecting to other ser +vers\n"; } sub client { my $target = shift; my $port = shift; my $status = `nc -z $target $port` or die "Can't open data connect +ion (port closed or host unreachable)"; print "Who do I encrypt to: "; my $keyname = <STDIN>; chomp( $keyname ); ReadMode('noecho'); print "PGP Key passphrase (not echoed): "; my $passphrase = <STDIN>; chomp $passphrase; print "\n"; # The user's return key won't be echoed ReadMode(0); # Reset term status open (NET, "|-", "nc $target $port") or die "Can't open netcat: $! +"; while( 0 == 0 ) { my $message = encrypt( $keyname, $passphrase ); last if $message eq "exit"; select(NET); # We select NET so $| will effect it $| = 1; # We can't buffer because of interactions with netcat. print $message . $message_separator; # Send it through the tub +es! } close NET; select(STDOUT); print "Connection Terminated.\n"; } sub encrypt { select(STDOUT); my $keyname = shift; my $passphrase = shift; print "Message: "; my $message = <STDIN>; chomp( $message ); return "exit" if( length($message) == 0 ); # Quit if blank message tie *ENCRYPT, 'GnuPG::Tie::Encrypt', recipient => $keyname, sign = +> 1, passphrase => $passphrase, armor => 1; print ENCRYPT $message; local $/ = undef; # Don't stop reading from ENCRYPT at a newline l +ike normal my $encrypted_message = <ENCRYPT>; close ENCRYPT; untie *ENCRYPT; return $encrypted_message; } sub daemon # Listen for incomming connections { my $port = shift or die "Usage: $0 <port_number>"; ReadMode('noecho'); print "PGP Key passphrase (not echoed): "; my $passphrase = <STDIN>; chomp $passphrase; print "\n"; # The user's return key won't be echoed ReadMode(0); # Reset term status print( msg_time(), " Server started.\n"); open (NET, "-|", "nc -k -l $port" ) or die "Can't open netcat!"; local $/ = $message_separator; # Seperate off chosen symbol instea +d of newline while( <NET> ) { my $plaintext = decrypt($passphrase, $_); print( msg_time(), " ", $plaintext); } close NET; } sub msg_time { my( $hours, $minutes, $seconds ) = (localtime)[2,1,0]; return "$hours:$minutes:$seconds"; } sub decrypt { my $passphrase = shift; my $message = shift; tie *DECRYPT, 'GnuPG::Tie::Decrypt', passphrase => $passphrase; print DECRYPT $message; # Here's where I error out my $plaintext_message = <DECRYPT>; close DECRYPT; untie *DECRYPT; return $plaintext_message; }