There are two Perl modules for RSA encryption Crypt::RSA and Crypt::OpenSSL::RSA. The former is much more complete that the latter. However Crypt::RSA, being pure Perl, is slower that the OpenSSL, which is really just a wrapper around the OpenSSL libraries. The other issue is that Crypt::RSA uses it's own key file formats. Not a major issue if you are just working in Perl, but if you are sharing keys with programs using OpenSSL, you need to jump through some key managment hoops.

Here's a simple work around. Crypt::OpenSSL::RSA expects a decrypted PEM format string. You can get one by using Convert::PEM as in intermediary. It's a little ugly because you end up decoding and then re-encoding the key, but it works. The following function takes two augments a key file path and a password. If the password in undefined, it simply reads the key, otherwise it decrypts the key.

my $key_string = readPrivateKey(key.private','xxxx');
my $private = Crypt::OpenSSL::RSA->new_private_key($key_string) || die "$!";
# Read your cyphertext into $buffer
my $plaintext = $private->decrypt($buffer);

exit;

sub readPrivateKey {
  my ($file,$password) = @_;
  my $key_string;

  if (!$password) {
    open(PRIV,$file) || die "$file: $!";
    read(PRIV,$key_string,-s PRIV); # Suck in the whole file
    close(PRIV);
  } else {
    $key_string = decryptPEM($file,$password);
  }
  $key_string
}

sub decryptPEM {
  my ($file,$password) = @_;

  my $pem = Convert::PEM->new(
			      Name => 'RSA PRIVATE KEY',
			      ASN  => qq(
                  RSAPrivateKey SEQUENCE {
                      version INTEGER,
                      n INTEGER,
                      e INTEGER,
                      d INTEGER,
                      p INTEGER,
                      q INTEGER,
                      dp INTEGER,
                      dq INTEGER,
                      iqmp INTEGER
                  }
           ));


  my $pkey =
    $pem->read(Filename => $file, Password => $password);

  $pem->encode(Content => $pkey);
}

More Stuff