2012-08-27 12 views
5

que necesito para ser capaces de crear firmas JSON Web Token (que sólo acepta 'RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function' firmas), pero el aspirante CPAN obvia para esta tarea (Crypt::RSA) sólo generar firmas usando MD2, MD5 or SHA1.¿Hay una aplicación Perl de SHA256withRSA

¿Hay alguna otra biblioteca en algún lugar que haga lo que yo quiera? Si es necesario, podría hacer algo de piratería para llegar allí, pero eso no sería demasiado bonito.

+2

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

+0

@mob pero cómo configurar Crypt :: RSA con él? –

Respuesta

2

yo era capaz de encontrar un módulo que hice lo que quería: Crypt::OpenSSL::RSA

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

mucho más fácil que se extiende Crypt :: RSA , pero fue extrañamente un tanto difícil de encontrar.

2

Parece que tuvo que modificar la 'Cripta :: RSA :: SS :: PKCS1v15.pm' para agregar el soporte SHA256. No es tan difícil, puede probar esta versión parcheada:

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

Sí, parece que es más o menos lo que tendré que hacer. Lo haré como un nuevo módulo (algo así como Crypt :: RSA :: SS :: PKCS1v15 :: SHA256) en lugar de solo parchearlo localmente. Aclamaciones. – Cebjyre

+0

@Cebjyre Estoy de acuerdo contigo. Tener un nuevo módulo parece más razonable para esto. ;) –

+0

Me quedé atrapado en la creación del nuevo módulo, luego me di cuenta de que 'Crypt :: RSA' usa su propio formato de clave extravagante, así que busqué otra búsqueda y encontré' Crypt :: OpenSSL :: RSA'. Hay una posibilidad decente de que todavía haré un módulo para manejar todo el proceso de JWT, pero afortunadamente ya no tengo que preocuparme por este componente en particular. – Cebjyre

Cuestiones relacionadas