You are correct. The public part of the key is not required for
RSA signature. I have no idea why perl code produces different
signature.
Aleksey
Antti S. Lankila wrote:
I hit this small issue while using xmlsec1 to double-check an unrelated
Perl implementation of XML-DSig. The basic work of what I'm doing is
performed by the Perl class, but the results are always double-checked
with xmlsec1 while developing.
It should be possible to sign an XML document with SHA1-RSA knowing
nothing else but the private exponent and the modulus, right? That is,
you need the private key to perform signature validation, but not the
public key. The only new information the RSA public key provides is the
public exponent.
So I go and extract the N and D parameters from some certificate, which
are large integers, and encode them into Base64 and store them into a
document like this:
<?xml version="1.0" encoding="UTF-8"?>
<Keys xmlns="http://www.aleksey.com/xmlsec/2002">
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<KeyValue>
<RSAKeyValue>
<Modulus>$modulus</Modulus>
<Exponent>AQAB</Exponent>
<PrivateExponent
xmlns="http://www.aleksey.com/xmlsec/2002">$exponent</PrivateExponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>
</Keys>
But here, I find I have to specify AQAB (base64 for 65537) as the
Exponent, or the signature computation gets a different result from my
Perl class. It appears that the differs if I substitute some other,
valid Base64-encoded value here, such as 1, which is AQ==. Therefore, it
seems clear that xmlsec1 makes some use of this information. The Perl
code I got does not need or use the public exponent for signature
computation, so what gives?
The command line I am using is:
% xmlsec1 sign --keys-file "the-above-file.xml" "file-to-be-signed.xml"
It's noteworthy that I am not necessarily operating with x509
certificates here. Sometimes yes, but often I only get the RSA
parameters from some metadata files. Therefore, I need the most generic
way to deal with this which is the construction of the keys file from
the minimal set of data available.
For the record, the Perl code for calculating a signature is here:
# Crypt::RSA is a stock module. It implements SHA1-RSA for us.
my $pkcs = Crypt::RSA::SS::PKCS1v15->new();
$signature = $pkcs->sign(
Message => $xml_to_sign,
Key => $self->{private_key},
) || die $pkcs->errstr;
$xml_to_sign is, naturally, the canonicalized version of the SignedInfo
element. The instance variable $self->{private_key} is constructed from
the RSA parameters as follows:
my $key = Crypt::RSA::Key::Private->new();
$key->n(Math::Pari::_hex_cvt($n));
$key->d(Math::Pari::_hex_cvt($d));
$self->{private_key} = $key;
(There is a bug in Crypt::RSA::Key::Private necessiating an explicit
call to _hex_cvt(). The input $n and $d are hex strings like
"0123456789abcdef". The lines simply set the n and d parameters into the
key, nothing more.) The noteworthy fact here is the complete absence of
the $e parameter.
_______________________________________________
xmlsec mailing list
[email protected]
http://www.aleksey.com/mailman/listinfo/xmlsec