2012-08-27 3 views
5

のがperlの実装である私は(だけ'RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function'署名を受け入れる)JSONウェブトークンの署名を作ることができるようにする必要がありますが、このタスク(Crypt::RSA)のための明白なCPANの候補はMD2, MD5 or SHA1を使用して署名を生成します。がSHA256withRSA

どこか別の場所にライブラリがありますか?必要に応じて、私はそこに着くために少しハッキングをすることができるはずですが、あまりにもかわいくないでしょう。

+2

['Digest :: SHA'?](http://search.cpan.org/perldoc?Digest::SHA) – mob

+0

@mobどのようにCrypt :: RSAを設定するのですか? –

答えて

2

:それはそう難しいことではない、あなたはこのパッチを適用したバージョンを試すことができますCrypt::OpenSSL::RSA

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

そんなに簡単に墓所を拡張するより:: RSAしかし、それは奇妙な種類の見つけるのは難しいです。

2

SHA256をサポートするために、 'Crypt :: RSA :: SS :: PKCS1v15.pm'を修正する必要があるようです。私は私が望んでいたモジュールを見つけることができた

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

ええ、それは私が行かなければならない方法であるように見えます。私は新しいモジュール(Crypt :: RSA :: SS :: PKCS1v15 :: SHA256のようなものです)ではなく、ローカルでパッチを当てるだけです。乾杯。 – Cebjyre

+0

@Cebjyre私はあなたに同意します。新しいモジュールをもっと妥当に見せてください。 ;) –

+0

私は新しいモジュールを作ってしまったので、 'Crypt :: RSA'は独自の不自然なキーファイルフォーマットを使用していることに気づき、別のハントに行き、' Crypt :: OpenSSL :: RSA'を見つけました。 JWTのプロセス全体を処理するためのモジュールをまだ用意していますが、幸い私はこの特定のコンポーネントについてもう心配する必要はありません。 – Cebjyre