view release on metacpan or search on metacpan
- Added strict and warnings to all .pm files.
- Converted RSA.pm to UTF-8 and added POD directive
- Make pretty maurer prime generation output with Verbosity.
0.01 2012-12-28
- Add test for h2osp, pss sign and verify with salt.
- Faster versions of some of the helper functions.
- Switch from Digest::SHA1 to Digest::SHA, and add SHA256.
- The following Crypt::RSA 1.99 defects have been fixed or made irrelevant
due to no longer using Math::Pari:
RT 52689 consider moving Crypt::RSA to Math::BigInt?
RT 76655 Version 1.99's META.yml says version is 1.97
Changes.old view on Meta::CPAN
* Numerical parameters of ::Key::Public and ::Key::Private can be
assigned perl strings, hex strings, or hex numbers.
1.30 March 25, 2001
* Documented Crypt::RSA methods
* Added ASCII armour support to Crypt::RSA::encrypt(), decrypt(), sign()
and verify() using Convert::ASCII::Armour
* Crypt::RSA will now work with any encryption/signing scheme as long as
they provide the same method interface as Crypt::RSA::EME::OAEP and
Crypt::RSA::SSA::PSS
* Wrote ::EME::OAEP::version() and ::SSA::PSS::version(). The next
release will include support for version specific operation in ::EME::*
and ::PSS::*
* Added and corrected documentation for ::EME::OAEP and ::SSA::PSS
1.25 March 12, 2001
* Wrote Crypt::RSA::sign() and Crypt::RSA::verify()
* Added tests for sign and verify to t/11-wrapper.t
* Bugfix in Crypt::RSA::EME::OAEP::hash() and mgf()
$self was being fed to the digest
* Bugfix in Crypt::RSA::SSA::PSS::hash() and mgf()
1.24 March 11, 2001
* Bug fix in Crypt::RSA::EME::OAEP::decode()
GMP and Pari backends.
All of the existing bug reports have been addressed, as well as adding
a few new features such as
PERFORMANCE
Performance using GMP is 3-10 times faster than the Crypt::RSA 1.99.
Using Math::BigInt::Pari, it is about half the speed at signing, and
on par when verifying.
If neither GMP nor Pari are available, performance is very slow, from
10x to 200x slower. However this is an environment where the original
code could not run.
Time to run test suite on my machine:
4 seconds with GMP and Math::Prime::Util::GMP
10 seconds with GMP
17 seconds with Pari (no GMP)
91 seconds with Calc (no GMP and no Pari)
just fundamentally broken and a _huge_ pain to work around.
- The test suites do almost no failure testing. Use Devel::Cover to see all
the failure cases that aren't covered.
- Look into allowing other SHA hashes for PSS and OAEP.
- Decide if RIPEMD160 should be non-optional. Module version 0.05 looks like
it has an excellent test pass rate.
- t/16-serialize.t is just verifying we don't die horribly. We should verify
that it's actually working.
- t/90-release-perlcritic.t
t/92-release-pod-coverage.t
lib/Alt/Crypt/RSA/BigInt.pm view on Meta::CPAN
- Crypt::Random => Math::Prime::Util
All operations are now performed using Math::BigInt, and prefer the
GMP and Pari backends.
=head1 PERFORMANCE
Performance using GMP is 3-10 times faster than Crypt::RSA 1.99.
Using Math::BigInt::Pari, it is about half the speed at signing, and
on par when verifying.
If neither GMP nor Pari are available, performance is very slow, from
10x to 200x slower. However this is an environment where the original
code could not run.
=head1 AUTHORS
Vipul Ved Prakash wrote the original Crypt::RSA.
Dana Jacobsen did the changes to Math::BigInt.
lib/Crypt/RSA.pm view on Meta::CPAN
Version => $self->{ss}->version() },
Content => { Signature => $signature },
);
}
return $signature;
}
sub verify {
my ($self, %params) = @_;
if ($params{Armour} || $params{Armor}) {
my $decoded = $self->{pp}->unarmour ($params{Signature}) ||
return $self->error ($self->{pp}->errstr());
$params{Signature} = $$decoded{Content}{Signature}
}
my $verify = $self->{ss}->verify (%params) ||
return $self->error ($self->{ss}->errstr, $params{Key}, \%params);
return $verify;
}
sub blocksize {
my ($blocksize, $ptsize) = @_;
return $ptsize if $blocksize == -1;
return 0 if $blocksize < 1;
return $blocksize;
lib/Crypt/RSA.pm view on Meta::CPAN
) || die $rsa->errstr();
my $signature =
$rsa->sign (
Message => $message,
Key => $private
) || die $rsa->errstr();
my $verify =
$rsa->verify (
Message => $message,
Signature => $signature,
Key => $public
) || die $rsa->errstr();
=head1 NOTE
This manual assumes familiarity with public-key cryptography and the RSA
algorithm. If you don't know what these are or how they work, please refer
to the sci.crypt FAQ[15]. A formal treatment of RSA can be found in [1].
lib/Crypt/RSA.pm view on Meta::CPAN
Finally, the Crypt::RSA module provides a convenient, DWIM wrapper around
the rest of the modules in the bundle.
=head1 SECURITY OF PADDING SCHEMES
It has been conclusively shown that textbook RSA is insecure[3,7]. Secure
RSA requires that plaintext is padded in a specific manner before
encryption and signing. There are four main standards for padding: PKCS
#1 v1.5 encryption & signatures, and OAEP encryption & PSS signatures.
Crypt::RSA implements these as four modules that
provide overloaded encrypt(), decrypt(), sign() and verify() methods that
add padding functionality to the basic RSA operations.
Crypt::RSA::ES::PKCS1v15(3) implements PKCS #1 v1.5 encryption,
Crypt::RSA::SS::PKCS1v15(3) implements PKCS #1 v1.5 signatures,
Crypt::RSA::ES::OAEP(3) implements Optimal Asymmetric Encryption and
Crypt::RSA::SS::PSS(3) Probabilistic Signatures.
PKCS #1 v1.5 schemes are older and hence more widely deployed, but PKCS #1
v1.5 encryption has certain flaws that make it vulnerable to
chosen-cyphertext attacks[9]. Even though Crypt::RSA works around these
lib/Crypt/RSA.pm view on Meta::CPAN
Private key of the sender, a Crypt::RSA::Key::Private(3) or
compatible object.
=item B<Armour>
A boolean parameter that forces the computed signature to be post
processed.
=back
=item B<verify()>
verify() verifies an RSA signature with a public key using the signature
scheme bound to the object. The default scheme is PSS. verify() returns a
true value on success and undef on failure. It takes a hash as argument
with following keys:
=over 4
=item B<Message>
A signed message, a string of arbitrary length.
=item B<Key>
lib/Crypt/RSA/Primitives.pm view on Meta::CPAN
sub core_sign {
my ($self, %params) = @_;
$params{Cyphertext} = $params{Message} || $params{Plaintext};
return $self->core_decrypt (%params);
}
sub core_verify {
my ($self, %params) = @_;
$params{Plaintext} = $params{Signature};
return $self->core_encrypt (%params);
}
1;
=head1 NAME
Crypt::RSA::Primitives - RSA encryption, decryption, signature and verification primitives.
=head1 SYNOPSIS
my $prim = new Crypt::RSA::Primitives;
my $ctxt = $prim->core_encrypt (Key => $key, Plaintext => $string);
my $ptxt = $prim->core_decrypt (Key => $key, Cyphertext => $ctxt);
my $sign = $prim->core_sign (Key => $key, Message => $string);
my $vrfy = $prim->core_verify (Key => $key, Signature => $sig);
=head1 DESCRIPTION
This module implements RSA encryption, decryption, signature and
verification primitives. These primitives should only be used in the
context of an encryption or signing scheme. See Crypt::RSA::ES::OAEP(3),
and Crypt::RSA::SS::PSS(3) for the implementation of two such schemes.
=head1 ERROR HANDLING
lib/Crypt/RSA/SS/PKCS1v15.pm view on Meta::CPAN
return $self->error ($self->errstr, \$key, \%params, \$M);
}
my $m = os2ip ($em);
my $sig = $self->{primitives}->core_sign (Key => $key, Message => $m);
return i2osp ($sig, $k);
}
sub verify {
my ($self, %params) = @_;
my $key = $params{Key}; my $M = $params{Message} || $params{Plaintext};
my $S = $params{Signature};
return $self->error ("No Message or Plaintext parameter", \$key, \%params) unless $M;
return $self->error ("No Key parameter", \$M, \$S, \%params) unless $key;
return $self->error ("No Signature parameter", \$key, \$M, \%params) unless $S;
my $k = octet_len ($key->n);
return $self->error ("Invalid signature.", \$key, \$M, \%params) if length($S) != $k;
my $s = os2ip ($S);
my $m = $self->{primitives}->core_verify (Key => $key, Signature => $s) ||
$self->error ("Invalid signature.", \$M, $key, \%params);
my $em = i2osp ($m, $k) ||
return $self->error ("Invalid signature.", \$M, \$S, $key, \%params);
my $em1;
unless ($em1 = $self->encode ($M, $k)) {
return $self->error ($self->errstr, \$key, \%params, \$M)
if $self->errstr eq "Message too long.";
return $self->error ("Modulus too short.", \$key, \%params, \$M)
if $self->errstr eq "Intended encoded message length too short.";
}
lib/Crypt/RSA/SS/PKCS1v15.pm view on Meta::CPAN
my $self = shift;
return $self->{VERSION};
}
sub signblock {
return -1;
}
sub verifyblock {
my ($self, %params) = @_;
return octet_len($params{Key}->n);
}
1;
=head1 NAME
Crypt::RSA::SS::PKCS1v15 - PKCS #1 v1.5 signatures.
lib/Crypt/RSA/SS/PKCS1v15.pm view on Meta::CPAN
my $pkcs = new Crypt::RSA::SS::PKCS1v15 (
Digest => 'MD5'
);
my $signature = $pkcs->sign (
Message => $message,
Key => $private,
) || die $pss->errstr;
my $verify = $pkcs->verify (
Message => $message,
Key => $key,
Signature => $signature,
) || die $pss->errstr;
=head1 DESCRIPTION
This module implements PKCS #1 v1.5 signatures based on RSA. See [13]
for details on the scheme.
lib/Crypt/RSA/SS/PKCS1v15.pm view on Meta::CPAN
=item B<Message>
Message to be signed, a string of arbitrary length.
=item B<Key>
Private key of the signer, a Crypt::RSA::Key::Private object.
=back
=head2 B<verify()>
Verifies a signature generated with sign(). Returns a true value on
success and false on failure. $self->errstr is set to "Invalid signature."
or appropriate error on failure. verify() takes a hash argument with the
following mandatory keys:
=over 4
=item B<Key>
Public key of the signer, a Crypt::RSA::Key::Public object.
=item B<Message>
lib/Crypt/RSA/SS/PSS.pm view on Meta::CPAN
my $salt = random_bytes($self->{hlen});
my $em = $self->encode ($M, $salt, $k-1);
my $m = os2ip ($em);
my $sig = $self->{primitives}->core_sign (Key => $key, Message => $m);
my $S = i2osp ($sig, $k);
return ($S, $salt) if wantarray;
return $S;
}
sub verify_with_salt {
my ($self, %params) = @_;
my $key = $params{Key}; my $M = $params{Message} || $params{Plaintext};
my $S = $params{Signature}; my $salt = $params{Salt};
return $self->error("No Key parameter", \$S, \%params) unless $key;
return $self->error("No Signature parameter", \$key, \%params) unless $S;
my $k = octet_len ($key->n);
my $em;
unless ($em = $self->encode ($M, $salt, $k-1)) {
return if $self->errstr eq "Message too long.";
return $self->error ("Modulus too short.", \$M, \$S, \$key, \%params) if
$self->errstr eq "Intended encoded message length too short.";
}
return $self->error ("Invalid signature.", \$M, \$S, $key, \%params) if length($S) < $k;
my $s = os2ip ($S);
my $m = $self->{primitives}->core_verify (Key => $key, Signature => $s) ||
$self->error ("Invalid signature.", \$M, \$S, $key, \%params);
my $em1 = i2osp ($m, $k-1) ||
return $self->error ("Invalid signature.", \$M, \$S, $key, \%params);
return 1 if $em eq $em1;
return $self->error ("Invalid signature.", \$M, \$S, $key, \%params);
}
sub verify {
my ($self, %params) = @_;
my $key = $params{Key}; my $M = $params{Message} || $params{Plaintext};
my $S = $params{Signature};
return $self->error("No Key parameter", \$S, \$M, \%params) unless $key;
return $self->error("No Signature parameter", \$key, \$M, \%params) unless $S;
return $self->error("No Message or Plaintext parameter", \$key, \$S, \%params) unless $M;
my $k = octet_len ($key->n);
my $s = os2ip ($S);
my $m = $self->{primitives}->core_verify (Key => $key, Signature => $s) ||
$self->error ("Invalid signature.", \$M, \$S, $key, \%params);
my $em1 = i2osp ($m, $k-1) ||
return $self->error ("Invalid signature.", \$M, \$S, $key, \%params);
return 1 if $self->verify_with_salt_recovery ($M, $em1);
return $self->error ("Invalid signature.", \$M, \$S, $key, \%params);
}
sub encode {
my ($self, $M, $salt, $emlen) = @_;
return $self->error ("Intended encoded message length too short.", \$M, \$salt )
if $emlen < 2 * $self->{hlen};
my $H = $self->hash ("$salt$M");
my $padlength = $emlen - (2*$$self{hlen});
my $PS = chr(0)x$padlength;
my $db = $salt . $PS;
my $dbmask = $self->mgf ($H, $emlen - $self->{hlen});
my $maskeddb = octet_xor ($db, $dbmask);
my $em = $H . $maskeddb;
return $em;
}
sub verify_with_salt_recovery {
my ($self, $M, $EM) = @_;
my $hlen = $$self{hlen};
my $emlen = length ($EM);
return $self->error ("Encoded message too short.", \$M, \$EM) if $emlen < (2*$hlen);
my $H = substr $EM, 0, $hlen;
my $maskeddb = substr $EM, $hlen;
my $dbmask = $self->mgf ($H, $emlen-$hlen);
my $db = octet_xor ($maskeddb, $dbmask);
my $salt = substr $db, 0, $hlen;
my $PS = substr $db, $hlen;
lib/Crypt/RSA/SS/PSS.pm view on Meta::CPAN
my $self = shift;
return $self->{VERSION};
}
sub signblock {
return -1;
}
sub verifyblock {
my ($self, %params) = @_;
return octet_len($params{Key}->n);
}
1;
=head1 NAME
Crypt::RSA::SS::PSS - Probabilistic Signature Scheme based on RSA.
=head1 SYNOPSIS
my $pss = new Crypt::RSA::SS::PSS;
my $signature = $pss->sign (
Message => $message,
Key => $private,
) || die $pss->errstr;
my $verify = $pss->verify (
Message => $message,
Key => $key,
Signature => $signature,
) || die $pss->errstr;
=head1 DESCRIPTION
PSS (Probabilistic Signature Scheme) is a provably secure method of
creating digital signatures with RSA. "Provable" means that the
lib/Crypt/RSA/SS/PSS.pm view on Meta::CPAN
=head2 B<version()>
Returns the version number of the module.
=head2 B<sign()>
Computes a PSS signature on a message with the private key of the signer.
In scalar context, sign() returns the computed signature. In array
context, it returns the signature and the random salt. The signature can
verified with verify() or verify_with_salt(). sign() takes a hash argument
with the following mandatory keys:
=over 4
=item B<Message>
Message to be signed, a string of arbitrary length.
=item B<Key>
Private key of the signer, a Crypt::RSA::Key::Private object.
=back
=head2 B<verify()>
Verifies a signature generated with sign(). The salt is recovered from the
signature and need not be passed. Returns a true value on success and
false on failure. $self->errstr is set to "Invalid signature." or
appropriate error on failure. verify() takes a hash argument with the
following mandatory keys:
=over 4
=item B<Key>
Public key of the signer, a Crypt::RSA::Key::Public object.
=item B<Message>
The original signed message, a string of arbitrary length.
=item B<Signature>
Signature computed with sign(), a string.
=item B<Version>
Version of the module that was used for creating the Signature. This is an
optional argument. When present, verify() will ensure before proceeding
that the installed version of the module can successfully verify the
Signature.
=back
=head2 B<verify_with_salt()>
Verifies a signature given the salt. Takes the same arguments as verify()
in addition to B<Salt>, which is a 20-byte string returned by sign() in
array context.
=head1 ERROR HANDLING
See ERROR HANDLING in Crypt::RSA(3) manpage.
=head1 BIBLIOGRAPHY
See BIBLIOGRAPHY in Crypt::RSA(3) manpage.
for (1 .. 4) {
$message .= "\n$message";
my $sig = $pss->sign (
Message => $message,
Key => $priv,
) || die $pss->errstr();
is ( $pss->verifyblock (Key => $priv), length($sig), "verifyblock" );
my $verify = $pss->verify (
Key => $pub,
Message => $message,
Signature => $sig,
) || die $pss->errstr;
ok ( $verify, "verify successful" );
}
# Again with salt
{
my $message = "Oh what can ail thee, knight-at-arms,\n Alone and palely loitering?\nThe sedge has withered from the lake,\n And no birds sing.";
my($sig, $salt) = $pss->sign( Message => $message, Key => $priv )
or die $pss->errstr();
my $verify = $pss->verify_with_salt (
Key => $pub,
Message => $message,
Signature => $sig,
Salt => $salt,
) || die $pss->errstr;
ok ( $verify, "verify with salt successful" );
}
sub readkeys {
my $n = "73834345487788514568533774308502691535472856730213458245198623 \
26913500918212899613538952044531113709736546304347778208211537 \
356895300653369009683166191489";
my $d = "42559776454402653689602825763344464625105789228943555733842995 \
t/11-wrapper.t view on Meta::CPAN
my $signature = $rsa->sign (
Message => $plaintext,
Key => $pri,
Armour => 1,
) || die $rsa->errstr();
# diag($signature);
like( $signature, qr/Scheme: Crypt::RSA::SS::PSS/, "RSA signature" );
my $verify = $rsa->verify (
Message => $plaintext,
Key => $pub,
Signature => $signature,
Armour => 1,
);
ok($verify, "Verified RSA signature");
}
t/14-ss-pkcs1v15.t view on Meta::CPAN
foreach my $hash (qw(MD2 MD5 SHA1 SHA224 SHA256 SHA384 SHA512)) {
my $pkcs = new Crypt::RSA::SS::PKCS1v15 ( Digest => $hash );
my $sig = $pkcs->sign (
Message => $message,
Key => $priv,
) || die $pkcs->errstr();
is( $pkcs->verifyblock(Key => $priv), length($sig), "verifyblock" );
my $verify = $pkcs->verify (
Key => $pub,
Message => $message,
Signature => $sig,
) || die $pkcs->errstr;
ok($verify, "Signed and verified using $hash hash");
}
# Not used
sub readkeys {
my $n = "73834345487788514568533774308502691535472856730213458245198623 \
26913500918212899613538952044531113709736546304347778208211537 \
t/15-benchmark.t view on Meta::CPAN
timethese ($count, {
'PSS-sign-CRT' => sub {
$pss->sign (
Message => $message,
Key => $priv2,
)
},
'PSS-verify-CRT' => sub {
$pss->verify (
Key => $pub2,
Message => $message,
Signature => $sigcrt,
)
},
'PSS-sign' => sub {
$sig = $pss->sign (
Message => $message,
Key => $priv,
)
},
'PSS-verify' => sub {
$pss->verify (
Key => $pub,
Message => $message,
Signature => $sig,
);
},
'PKCS-sign' => sub {
$sigpkcs = $pkcs->sign (
Message => $message,
Key => $priv,
t/15-benchmark.t view on Meta::CPAN
},
'PKCS-sign-CRT' => sub {
$pkcs->sign (
Message => $message,
Key => $priv2,
)
},
'PKCS-verify' => sub {
$pkcs->verify (
Key => $pub,
Message => $message,
Signature => $sigpkcs,
);
},
'PKCS-verify-CRT' => sub {
$pkcs->verify (
Key => $pub2,
Message => $message,
Signature => $sigcrtpkcs,
);
},
});
sub readkeys {
xt/perlcom-20010926.pl view on Meta::CPAN
Password => 'alice always awesome'
);
my $rsa = new Crypt::RSA;
print "sign...";
my $signature = $rsa->sign ( Message => $message, Key => $private );
print "read public...";
my $public = new Crypt::RSA::Key::Public(
Filename => "alice.public",
);
print "verify...";
$rsa->verify( Message => $message, Signature => $signature,
Key => $public ) ||
die "Signature doesn't verify!\n";
print "success\n";
}
sub gotsig { my $sig = shift; die "Die because SIG$sig\n"; }
END {
unlink 'alice.private' if -e 'alice.private';
unlink 'alice.public' if -e 'alice.public';
}
xt/ripemd160.pl view on Meta::CPAN
for (qw(RipeMD-160)) {
my $pkcs = new Crypt::RSA::SS::PKCS1v15 ( Digest => $_ );
my $sig = $pkcs->sign (
Message => $message,
Key => $priv,
) || die $pkcs->errstr();
#{ my $x = $sig; $x =~ s/[^[:print:]]/?/g; warn " sig = '$x'\n"; }
#$pkcs->verifyblock(Key => $priv);
my $verify = $pkcs->verify (
Key => $pub,
Message => $message,
Signature => $sig,
) || die $pkcs->errstr;
print "Digest $_ : SUCCESS\n";
}
xt/sha384.pl view on Meta::CPAN
for (qw(SHA256 SHA384 SHA512)) {
my $pkcs = new Crypt::RSA::SS::PKCS1v15 ( Digest => $_ );
my $sig = $pkcs->sign (
Message => $message,
Key => $priv,
) || die $pkcs->errstr();
#{ my $x = $sig; $x =~ s/[^[:print:]]/?/g; warn " sig = '$x'\n"; }
#$pkcs->verifyblock(Key => $priv);
my $verify = $pkcs->verify (
Key => $pub,
Message => $message,
Signature => $sig,
) || die $pkcs->errstr;
}