2013-03-31 130 views
1

我無法使用Crypt :: RSA和Crypt :: RSA在Perl中驗證PSS簽名簽名: :SS :: PSS。使用Crypt :: RSA和Crypt :: RSA :: SS :: PSS在Perl中無法驗證RSA 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 

其中:

  • 字符串 「Hello」,是指已通過設備簽署的緩衝區。
  • 「pubkey.pem」是設備的RSA公鑰,從設備 用PEM_write_RSA_PUBKEY()導出。
  • 「hello.sig」包含設備生成的二進制(原始)簽名。 (這是128字節,因爲填充。)

我想在Perl中使用Crypt :: RSA和Crypt :: RSA :: SS :: PSS來完成上述操作,並且無法獲取它工作。

我測試過這兩個模塊和I 能夠生成和在Perl驗證PSS簽名生成時,我自己的鑰匙,就像這樣:

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」包含設備的公鑰,轉換爲十進制字符串,插入到所讀取的「N」變量的領域:關鍵我在一個公共密鑰使用這樣的閱讀/由Crypt :: RSA :: Key編寫::上市。

但我不能讓它驗證:-(

我以爲我應該能夠表明它應該使用SHA1和AES-128(而不是,比方說,河豚)。
上午我找錯了樹?

謝謝...。

回答

0

不知道如何幫助你,如果不能夠讓你的文件和代碼測試,以調試。但是,雖然不是最好的解決方案,一個好的工作可以在Perl中使用系統調用。如果你能夠在命令提示符下驗證它,你可以使用一些選項來檢查它的方式。第一個是system

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

當你做到這一點,您會收到返回的退出代碼$return_code。如果您在命令提示符下驗證它的任何操作會在驗證失敗時退出並顯示錯誤代碼,那麼您知道一切順利時您將收到0,並且在出錯時收到另一個數字。

分析系統調用的答案,如果你想讀的實際答案,使用ID反引號其他方式:

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 127行。 所以我必須繼續尋找。 – user2228297