我需要能够制作 JSON Web 令牌签名(它只接受带有 SHA-256 哈希函数签名的 'RSASSA-PKCS1-V1_5-SIGN),但这项任务的明显 CPAN 竞争者(Crypt::RSA)只会使用MD2、MD5 或 SHA1生成签名。
是否有另一个图书馆可以做我想做的事?如有必要,我应该能够进行一些黑客攻击以到达那里,但这不会太漂亮。
我需要能够制作 JSON Web 令牌签名(它只接受带有 SHA-256 哈希函数签名的 'RSASSA-PKCS1-V1_5-SIGN),但这项任务的明显 CPAN 竞争者(Crypt::RSA)只会使用MD2、MD5 或 SHA1生成签名。
是否有另一个图书馆可以做我想做的事?如有必要,我应该能够进行一些黑客攻击以到达那里,但这不会太漂亮。
我能够找到一个符合我要求的模块:Crypt::OpenSSL::RSA
my $rsa = Crypt::OpenSSL::RSA->new_private_key($key);
$rsa->use_sha256_hash;
my $signature = $rsa->sign($message);
比扩展 Crypt::RSA 容易得多,但奇怪的是很难找到。
Looks like you had to modify the 'Crypt::RSA::SS::PKCS1v15.pm' to add the SHA256 supporting. It is not so difficult, you can try this patched version:
#!/usr/bin/perl -sw
##
## Crypt::RSA::SS:PKCS1v15
##
## Copyright (c) 2001, Vipul Ved Prakash. All rights reserved.
## This code is free software; you can redistribute it and/or modify
## it under the same terms as Perl itself.
##
## $Id: PKCS1v15.pm,v 1.6 2001/06/22 23:27:38 vipul Exp $
package Crypt::RSA::SS::PKCS1v15;
use strict;
use base 'Crypt::RSA::Errorhandler';
use Crypt::RSA::DataFormat qw(octet_len os2ip i2osp h2osp);
use Crypt::RSA::Primitives;
use Crypt::RSA::Debug qw(debug);
use Digest::SHA qw(sha1 sha256);
use Digest::MD5 qw(md5);
use Digest::MD2 qw(md2);
use Math::Pari qw(floor);
$Crypt::RSA::SS::PKCS1v15::VERSION = '1.99.1';
sub new {
my ($class, %params) = @_;
my $self = bless {
primitives => new Crypt::RSA::Primitives,
digest => $params{Digest} || 'SHA1',
encoding => {
MD2 => "0x 30 20 30 0C 06 08 2A 86 48
86 F7 0D 02 02 05 00 04 10",
MD5 => "0x 30 20 30 0C 06 08 2A 86 48
86 F7 0D 02 05 05 00 04 10",
SHA1 => "0x 30 21 30 09 06 05 2B 0E 03
02 1A 05 00 04 14",
SHA256 => "0x 30 31 30 0d 06 09 60 86
48 01 65 03 04 02 01 05
00 04 20",
},
VERSION => $Crypt::RSA::SS::PKCS1v15::VERSION,
}, $class;
if ($params{Version}) {
# do versioning here
}
return $self;
}
sub sign {
my ($self, %params) = @_;
my $key = $params{Key}; my $M = $params{Message} || $params{Plaintext};
return $self->error ("No Message or Plaintext parameter", \$key, \%params) unless $M;
return $self->error ("No Key parameter", \$M, \%params) unless $key;
my $k = octet_len ($key->n);
my $em;
unless ($em = $self->encode ($M, $k-1)) {
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";
}
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-1) ||
return $self->error ("Invalid signature.", \$M, \$S, $key, \%params);
my $em1;
unless ($em1 = $self->encode ($M, $k-1)) {
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.";
}
debug ("em: $em"); debug ("em1: $em1");
return 1 if $em eq $em1;
return $self->error ("Invalid signature.", \$M, \$key, \%params);
}
sub encode {
my ($self, $M, $emlen) = @_;
my $H;
if ($self->{digest} eq "SHA1") { $H = sha1 ($M) }
elsif ($self->{digest} eq "SHA256" ) { $H = sha256 ($M) }
elsif ($self->{digest} eq "MD5" ) { $H = md5 ($M) }
elsif ($self->{digest} eq "MD2" ) { $H = md2 ($M) }
my $alg = h2osp($self->{encoding}->{$self->{digest}});
my $T = $alg . $H;
$self->error ("Intended encoded message length too short.", \$M) if $emlen < length($T) + 10;
my $pslen = $emlen - length($T) - 2;
my $PS = chr(0xff) x $pslen;
my $em = chr(1) . $PS . chr(0) . $T;
return $em;
}
sub version {
my $self = shift;
return $self->{VERSION};
}
sub signblock {
return -1;
}
sub verifyblock {
my ($self, %params) = @_;
return octet_len($params{Key}->n);
}
1;