2013-03-31 3 views
1

Я не могу проверить подпись PSS-подпись в Perl с использованием Crypt :: RSA и Crypt :: RSA: : SS :: PSS.Устранение неполадок RSA PSS-подпись в Perl с Crypt :: RSA и Crypt :: RSA :: SS :: PSS

Вот ситуация:

У меня есть устройство, которое имеет 1024-битный RSA ключ, и данные знаки с помощью PSS, SHA1 и AES-128.

извлечь открытый ключ устройства успешно, сохраните его в файле с PEM_write_RSA_PUBKEY()

Я утра в состоянии проверить это в C/C++ с использованием RSA_verify_PKCS1_PSS(), а также с использованием OpenSSL в командной строке , как это:

echo -n hello | 
openssl dgst -verify pubkey.pem -signature hello.sig -sha1 \ 
            -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:20 

Где:

  • строка "привет" является буфером, который был подписан устройством.
  • «pubkey.pem» является открытым ключом RSA устройства, экспортированным с устройства с PEM_write_RSA_PUBKEY().
  • «hello.sig» содержит двоичную (необработанную) подпись, сгенерированную устройством. (Это 128 байт из-за заполнения.)

Я пытаюсь сделать это на Perl, используя Crypt :: RSA и Crypt :: RSA :: SS :: PSS, и не могу получить это работать.

Я проверил эти два модуль, и я я, способные генерировать и проверять подпись PSS в Perl при создании моего собственного ключа, как это:

use Crypt::RSA; 
use Crypt::RSA::SS::PSS; 

my ($message, $rsa, $pss, $signature, $verify); 
my ($public, $private); 


# The message to be encrypted 
# 
$message = "hello"; 


# Generate RSA key 
# 
$rsa = new Crypt::RSA; 
($public, $private) = $rsa->keygen(Size => 1024, Filename => "key"); 


# Generate PSS signature 
# 
$pss = new Crypt::RSA::SS::PSS; 

$signature = $pss->sign (Message => $message, Key => $private) || die $pss->errstr; 

$verify = $pss->verify (Message => $message, Key => $public, Signature => $signature) || die $pss->errstr; 

# $verify returns true, it worked. 

Таким образом, вместо того, чтобы создать свой собственный RSA ключ я прочитал в публичном ключе, используя что-то вроде этого:

$publicKey = new Crypt::RSA::Key::Public (Filename => "key.public" ); 
    ... 
# I pack the 256 character (128 byte) hex string of the signature 
# that's generated by the device. 
    $signature = pack ("H*", '03808458…..73E92'); 

Где «key.public» содержит открытый ключ устройства, преобразуется в десятичную строку, вставленную в «п» поле переменной, которая читается/написан Crypt :: RSA :: Key :: Общественные.

Но я не могу получить его, чтобы проверить :-(

Methinks я должен быть в состоянии указать, что следует использовать SHA1 и AES-128 (в отличие, скажем, Blowfish).
Am Я ложному дерево?

Спасибо ....

ответ

0

не знаете, как помочь вам в этом, не будучи в состоянии сделать тесты с файлами и кодом, чтобы отладить. Но, хотя и не самое лучшее решение, хороший рабочий стол может использоваться для использования системных вызовов в Perl. Если вы можете проверить его в командной строке, у вас есть некоторые варианты, чтобы проверить его таким образом. Первый system:

my $return_code = system("some command"); 
# or... 
my $return_code = system("command", "some", "args"); 

Когда вы сделаете это, вы получите возвращенный код выхода в $return_code. Если все, что вы делаете, чтобы проверить его в командной строке, завершается с кодом ошибки при сбое проверки, то вы знаете, что получите 0, когда все пойдет хорошо, и еще один номер, когда он пойдет не так.

Другой способ проанализировать ответ системного вызова, если вы хотите, чтобы прочитать фактический ответ, используя идентификационные кавычку:

my $answer = `some system call`; 
# or... 
my $answer = qx[some system call]; 

Делая это, вы будете захватить все, что отправляется на STDOUT самая системный вызов. Если вы хотите также захватить STDERR, вы можете перенаправить его в тот же звонок с помощью 2>&1 или что-то в этом роде. В этом случае вы не получите возвращаемый код выхода.

В зависимости от используемого метода, вы можете работать с ответом, как это:

if ($return_code == 0) { 
    print "Verified!"; 
} 
# or... 
if ($answer =~ /OpenSSL.*?Verification sucess.*?Signature code:(\d+)/) { 
    # I'm just making up stuff here, I don't know the answer of your command! 
    print "Verification succesful. Signature code was $1"; 
} 

Я надеюсь, что это помогает. Хотелось бы, чтобы я мог проверить ваш фактический сценарий и файлы, и я мог бы дать вам чисто-Perl-ответ, но это по крайней мере должно помочь вам двигаться вперед на данный момент.

Francisco

+0

Спасибо, Франциско. Запуск «openssl» в качестве внешней программы отлично работает (поскольку я могу проверить подпись из командной строки с помощью «openssl dgst»). Тем временем я обнаружил, что в одном из модулей есть какая-то ошибка: Math :: Pari или Crypt :: RSA, потому что когда я запускаю свой скрипт (как указано выше), иногда я получаю следующее ошибка: PARI: *** запрещенное разделение t_INT% t_REAL. на /usr/local/share/perl/5.14.2/Crypt/RSA/Key/Private.pm line 127. Так что мне придется продолжать искать. – user2228297

Смежные вопросы