Subject: | Crypt::OpenSSL::RSA sign() produces incorrect results? |
Date: | Mon, 2 Nov 2009 12:17:24 +0100 |
To: | <bug-Crypt-OpenSSL-RSA [...] rt.cpan.org> |
From: | Romain Wartel <Romain.Wartel [...] cern.ch> |
I am trying the sign messages and verify signatures with
Crypt::OpenSSL::RSA.
Unfortunately, I am unable to obtain consistent results with sign().
Please find a detailed example below, with perl-Crypt-OpenSSL-
RSA-0.25-1.el5.rf.
1. OpenSSL command line (openssl-0.9.7a-43.17.el4_7.2 and
openssl-0.9.8e-12.el5 tested)
[root@vtb-generic-66 ~]# cat /tmp/message
There is something fishy here.
[root@vtb-generic-66 ~]# openssl dgst -sha1 /tmp/message |awk '{print
$2}' > /tmp/digest
[root@vtb-generic-66 ~]# cat /tmp/digest
78c9bcffc794b2545c41fd500767a90db85aad3e
[root@vtb-generic-66 ~]#
[root@vtb-generic-66 ~]# openssl rsautl -sign -in /tmp/digest -inkey /
tmp/server.key | openssl enc -base64
JaM4WdomBQ1SCGeJer+17m4zIkxTlt6FD4h50BJXJWfbyhkyM2xlBYakeMJ5vLQg
i78/PyCWbpPXbsFyJQ/3i2ihUGf7EFBHiCQgeYpIrSH1uiiaEEYtaHZcXOJUYHFt
9eJsHiqyOxd0sZeoaxGJoFXsb9nUuqB6spHd9wwOhs8=
[root@vtb-generic-66 ~]#
(OpenSSL is used to sign the digest of the message)
2. Crypt::OpenSSL::RSA ($private_key is identical to /tmp/server.key)
#!/usr/bin/perl -w
use Crypt::OpenSSL::RSA;
use MIME::Base64;
use Digest::SHA1 qw(sha1 sha1_hex);
my $message = "There is something fishy here.\n";
my $rsa_priv = Crypt::OpenSSL::RSA->new_private_key($private_key);
$rsa_priv->use_pkcs1_padding();
$rsa_priv->use_sha1_hash();
# METHOD 1
# Sign = sha1 digest + encryption with private key
my $signature = $rsa_priv->sign($message);
$signature = MIME::Base64::encode_base64($signature) ;
# METHOD 2
# sha1 digest
my $message_digest = sha1_hex($message);
$message_digest .= "\n"; # (don't understand why this is needed)
# encryption with private key
my $signature2 = $rsa_priv->private_encrypt($message_digest);
$signature2 = MIME::Base64::encode_base64($signature2) ;
print "Message digest: \n$message_digest\n";
print "Crypt-OpenSSL-RSA private_encrypt():\n$signature2\n";
print "Crypt-OpenSSL-RSA sign():\n$signature\n";
my $openssl_signature= "JaM4WdomBQ1SCGeJer
+17m4zIkxTlt6FD4h50BJXJWfbyhkyM2xlBYakeMJ5vLQg
i78/PyCWbpPXbsFyJQ/3i2ihUGf7EFBHiCQgeYpIrSH1uiiaEEYtaHZcXOJUYHFt
9eJsHiqyOxd0sZeoaxGJoFXsb9nUuqB6spHd9wwOhs8=";
print "Sig (OpenSSL CLI):\n". $openssl_signature . "\n\n";
------------------8<---------------
Running the script will produce:
# /tmp/bug.pl
Message digest:
78c9bcffc794b2545c41fd500767a90db85aad3e
Crypt-OpenSSL-RSA private_encrypt():
JaM4WdomBQ1SCGeJer+17m4zIkxTlt6FD4h50BJXJWfbyhkyM2xlBYakeMJ5vLQgi78/
PyCWbpPX
bsFyJQ/
3i2ihUGf7EFBHiCQgeYpIrSH1uiiaEEYtaHZcXOJUYHFt9eJsHiqyOxd0sZeoaxGJoFXs
b9nUuqB6spHd9wwOhs8=
Crypt-OpenSSL-RSA sign():
zdBkLSvMmbuVNL3rGv/
i5VToyMEJEaKnyFfHHTinKHypzThHGKb08c9U2JPGculReSoFDeH051ol
OLbFERt7Hpl0yqM1r1PJ5J973yveJDeJ2W+9Nq/
4jdSH4KRiKbgUBgsHXDgkPtysCVT1lRc8ye7w
Ouddb5G5EFUVSsE3MPU=
Sig (OpenSSL CLI):
JaM4WdomBQ1SCGeJer+17m4zIkxTlt6FD4h50BJXJWfbyhkyM2xlBYakeMJ5vLQg
i78/PyCWbpPXbsFyJQ/3i2ihUGf7EFBHiCQgeYpIrSH1uiiaEEYtaHZcXOJUYHFt
9eJsHiqyOxd0sZeoaxGJoFXsb9nUuqB6spHd9wwOhs8=
Conclusions:
- Both OpenSSL CLI and Perl digests are identical
- sha1_hex() + private_encrypt() produces the expected output
- Sign produces a different output
From the documentation:
sign: Sign a string using the secret (portion of the) key.
use_sha1_hash: Use the RFC 3174 Secure Hashing Algorithm (FIPS 180-1)
when signing and verifying messages. This is the default.
Finally, note that all OpenSSL calls are using PKCS #1 v1.5 padding,
the issue is unlikely to be linked to a padding issue?
Thanks for your interest in this issue,
Romain.
--
Romain Wartel Romain.Wartel@cern.ch
EGEE Operational Security Coordination Team
C.E.R.N. http://www.cern.ch/LCG
Information Technology Division http://www.eu-egee.org/security
Bat.28-R-016 http://cern.ch/security
CH-1211 Geneva 23, Switzerland