2012-08-27 27 views
5

Tôi cần có khả năng tạo chữ ký mã Web JSON (chỉ chấp nhận 'RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function' chữ ký), nhưng đối tượng CPAN rõ ràng cho tác vụ này (Crypt::RSA) sẽ chỉ tạo chữ ký bằng cách sử dụng MD2, MD5 or SHA1.Có thực hiện perl SHA256withRSA

Có thư viện nào khác ở đâu đó sẽ làm những gì tôi muốn không? Nếu cần thiết, tôi sẽ có thể làm một chút hacking để đạt được điều đó, nhưng điều đó sẽ không quá đẹp.

+2

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

+0

@mob nhưng cách cấu hình Crypt :: RSA với nó? –

Trả lời

2

tôi đã có thể tìm thấy một mô-đun đó đã làm những gì tôi muốn: Crypt::OpenSSL::RSA

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

Vì vậy, dễ dàng hơn nhiều so với mở rộng Crypt :: RSA , nhưng nó rất khó tìm.

2

Có vẻ như bạn phải sửa đổi 'Crypt :: RSA :: SS :: PKCS1v15.pm' để thêm hỗ trợ SHA256. Nó không phải là quá khó khăn, bạn có thể thử phiên bản này vá:

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

Vâng, có vẻ như đó là cách tôi sẽ phải đi. Tôi sẽ làm nó như là một mô-đun mới (một cái gì đó như Crypt :: RSA :: SS :: PKCS1v15 :: SHA256) thay vì chỉ vá nó cục bộ mặc dù. Chúc mừng. – Cebjyre

+0

@Cebjyre Tôi đồng ý với bạn. Có một mô-đun mới có vẻ hợp lý hơn cho việc này. ;) –

+0

Tôi gặp khó khăn trong việc tạo mô-đun mới, sau đó tôi nhận ra rằng 'Crypt :: RSA' sử dụng định dạng tệp khóa chính của nó, vì vậy tôi đã đi tìm kiếm khác và tìm thấy' Crypt :: OpenSSL :: RSA'. Có một cơ hội tốt, tôi vẫn sẽ làm một mô-đun để xử lý toàn bộ quá trình JWT, nhưng may mắn thay tôi không phải lo lắng về thành phần đặc biệt này nữa. – Cebjyre

Các vấn đề liên quan