[X-Unix] En/Decrypt Mismatch: Command-Line openssl vs. Perl's Crypt::OpenSSL::RSA

Jerry Krinock jerry at ieee.org
Wed Aug 20 13:59:22 PDT 2008


Well, I got this working, although I there are several things that  
don't seem to work they way they should.  Summary:  Must use perl  
function private_encrypt() instead of sign(), even though, to generate  
the same signature, the command-line tool must use -sign.  Must use  
the SHA1 digest generated by command-line tool, since $rsa_priv- 
 >use_sha1_hash() has no effect on private_encrypt().

I don't understand this well enough to say that these are bugs.  More  
comments are in the code in case anyone is interested.

Here are my revised commands/code and working results, starting with  
the command-line:

###############################################################
# Create private key
jk$ openssl genrsa -out Test248.private.pem
Generating RSA private key, 512 bit long modulus
.........++++++++++++
.............++++++++++++
e is 65537 (0x10001)

# Create SHA1 digest of message "Bonehead".
# The, write digest to file for later use by perl script.
# Finally, sign the digest using the key in file Test248.private.pem
# and PKCS padding.  Why PKCS?  See note [1].
echo -n "Bonehead" > clearMsg.txt
openssl dgst -sha1 -binary -out msgDigest clearMsg.txt
cat msgDigest | openssl rsautl -pkcs -sign -inkey Test248.private.pem - 
hexdump

0000 - 8a c6 56 19 97 f5 e7 16-20 30 f2 2f 0e af 7c 28
0010 - df 9d cd 5a 0e b0 11 c1-cc bb f2 3b 03 87 f0 96
0020 - 0d ce b4 55 dc 69 81 bc-30 40 75 9d 74 b8 b7 bd
0030 - 3b 15 a0 5d c2 db ab 9a-8d d3 f2 4b 77 e1 e9 a1
###

Now create the same signature using a Crypt::OpenSSL in Perl:

###
#!/usr/local/bin/perl -w

use strict ;
use warnings ;

use Crypt::OpenSSL::Random ;
use Crypt::OpenSSL::RSA ;

# Read in key from file
my $private_key_string = "" ;
my $key_path = "/Users/jk/Documents/SheepSystems/Keys/ 
Test248.private.pem" ;
open (KEY_FILE, $key_path) ;
while (my $line = <KEY_FILE>) {
    $private_key_string .= $line ;
}
close(KEY_FILE);

my $rsa_priv = Crypt::OpenSSL::RSA- 
 >new_private_key($private_key_string);

$rsa_priv->use_pkcs1_padding() ;
=com
The above affects encrypting with the private key
but does not affect signature generation.
It is necessary when using the private_encrypt().
Without it, private_encrypt() will fail/error.
I believe the problem is that OpenSSL does not
support oaep padding for signing, which is what you're
doing when you encrypt with the private key, despite doc to
the contrary.  See note [1].
=cut

# $rsa_priv->use_sha1_hash() ;
# The above has no effect on the output of the
# private_encrypt() method.

my $msgDigest ;
my $msgDigest_path = "/Users/jk/Documents/SheepSystems/Keys/msgDigest" ;
open (MSG_DIGEST_FH, $msgDigest_path) ;
# SHA1 Digest is 20 bytes...
read MSG_DIGEST_FH, $msgDigest, 20 ;
close(MSG_DIGEST_FH) ;
my $output = $rsa_priv->private_encrypt($msgDigest);
# If you use sign() instead of private_encrypt()
# above you get a different output.  This does not make sense
# to me because I thought that signing was the same as
# encrypting with the private key.
my $outputHex = showHex($output) ;
print "$outputHex\n" ;

# sub showHex [2]

###

Running the above script, I get this:

64 bytes:
8a c6 56 19 97 f5 e7 16 20 30 f2 2f 0e af 7c 28
df 9d cd 5a 0e b0 11 c1 cc bb f2 3b 03 87 f0 96
0d ce b4 55 dc 69 81 bc 30 40 75 9d 74 b8 b7 bd
3b 15 a0 5d c2 db ab 9a 8d d3 f2 4b 77 e1 e9 a1

###

which matches the output from the command-line openssl.

Thanks for reading.  If anyone can explain some of the anomalies  
noted, let us know.

Jerry


[1] The reason I used PKCS padding (-pkcs) is because if I change it   
to -oaep in the command-line test, I get an error message.  This does  
not make sense because the version on my Mac (OS X 10.5) is OpenSSL  
0.9.7l.

and "RSA_padding_add_PKCS1_OAEP() and RSA_padding_check_PKCS1_OAEP()  
were added in OpenSSL 0.9.2b" according to documentation:
http://openssl.org/docs/crypto/RSA_padding_add_PKCS1_type_1.html#

[2] See prior message


More information about the X-Unix mailing list