【问题标题】:Is there a perl implementation of SHA256withRSA是否有 SHA256withRSA 的 perl 实现
【发布时间】:2012-08-21 23:09:11
【问题描述】:

我需要能够制作 JSON Web Token 签名(仅接受 'RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function' 签名),但该任务的明显 CPAN 竞争者 (Crypt::RSA) 将仅使用 MD2, MD5 or SHA1 生成签名。

是否有另一个图书馆可以做我想做的事?如有必要,我应该能够做一些黑客攻击到达那里,但这不会太漂亮。

【问题讨论】:

标签: perl cryptography pkcs#1


【解决方案1】:

我找到了一个我想要的模块:Crypt::OpenSSL::RSA

my $rsa = Crypt::OpenSSL::RSA->new_private_key($key);
$rsa->use_sha256_hash;
my $signature = $rsa->sign($message);

比扩展 Crypt::RSA 容易得多,但奇怪的是很难找到它。

【讨论】:

    【解决方案2】:

    看起来您必须修改“Crypt::RSA::SS::PKCS1v15.pm”以添加 SHA256 支持。没那么难,你可以试试这个补丁版本:

    #!/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;
    

    【讨论】:

    • 是的,看起来这就是我必须走的路。我将把它作为一个新模块(类似于 Crypt::RSA::SS::PKCS1v15::SHA256)而不是仅仅在本地修补它。干杯。
    • @Cebjyre 我同意你的看法。有一个新模块看起来更合理。 ;)
    • 我陷入了制作新模块的困境,然后我意识到Crypt::RSA 使用自己古怪的密钥文件格式,所以我又去寻找Crypt::OpenSSL::RSA。很有可能我仍然会做一个模块来处理整个 JWT 流程,但幸运的是我不必再担心这个特定的组件了。
    猜你喜欢
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 2017-12-27
    • 1970-01-01
    • 2016-09-11
    • 2011-12-11
    • 1970-01-01
    • 2010-10-24
    相关资源
    最近更新 更多