2017-05-09 59 views
7

我想做一個RRSIG驗證,我想在PHP中使用openssl庫。但是我有一個問題將公鑰傳遞給openssl_verify函數。驗證RRSIG與PHP使用openssl

這是一個基本代碼, 使用Net/DNS2庫來執行帶有DNSSEC選項的DNS查詢。 並獲得DNSKEY和RRSIG。

<?php 

require_once 'Net/DNS2.php'; 

$r = new Net_DNS2_Resolver(array('nameservers' => array('127.0.0.1'))); 
$r->dnssec = true; 

try { 
     $result = $r->query('ip4afrika.nl', 'DNSKEY'); 

} catch(Net_DNS2_Exception $e) { 

     echo "::query() failed: ", $e->getMessage(), "\n"; 
     die(); // 
} 

// print_r($result->answer); 

$public_key_bin = base64_decode($result->answer[0]->key) ; 
$public_key_str = $result->answer[0]->key; //echo $public_key_str; die(); 
// $public_key_res = openssl_x509_parse($public_key_bin); 
$public_key_res = openssl_x509_read($public_key_str); 
// $public_key_res = openssl_pkey_get_public($public_key_str); 

while ($msg = openssl_error_string()) echo $msg . PHP_EOL; 

我收到此錯誤信息,

時使用:

$public_key_res = openssl_x509_read($public_key_str); 

PHP Warning: openssl_x509_read(): supplied parameter cannot be 
coerced into an X509 certificate! in /src/Net_DNS2-1.4.3/i.php on line 
34 PHP Stack trace: PHP 1. {main}() /src/Net_DNS2-1.4.3/i.php:0 PHP 
2. openssl_x509_read() /src/Net_DNS2-1.4.3/i.php:34 error:0906D06C:PEM routines:PEM_read_bio:no start line 

所以我嘗試添加BEGIN/END頭

$public_key_str = '-----BEGIN CERTIFICATE-----' . PHP_EOL . $result->answer[0]->key . PHP_EOL . '-----END CERTIFICATE-----' ; 

,並得到該錯誤消息,

error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag 
error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error 
error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib 

因此,我似乎餵了功能錯誤的格式,我仍然使用谷歌搜索,但任何幫助將受到歡迎。

最後,我想用驗證簽名:

openssl_verify($data, $signature, $public_key_res, 'RSA-SHA256'); 
+0

難道你看@ http://php.net/manual/en/function.openssl-verify.php。他們有很好的例子 –

+0

是的,我做了@E_p,我的問題是如何將我從DNS查詢中獲得的密鑰傳遞給函數,無論我嘗試使用哪種格式,我都會在某種方式中得到有關密鑰格式不正確的錯誤。 – Rabin

+0

是否有可能,當你獲得密鑰時,它有額外的空白或其他可以創建該問題的東西? –

回答

0

PHP_EOL是平臺,不知道是什麼平臺,你正在測試這個代碼,但嘗試'\n'明確更換不變。看看是否有幫助。

+0

沒有任何不同。 – Rabin

2

簡短的回答:

如果你只需要在PHP中的能力,你可以只使用https://github.com/metaregistrar/php-dnssec-validator

龍答:

原因無法加載密鑰數據是因爲它是在一個稍微不同的格式。據rfc3110

Field    Size 
-----    ---- 
exponent length 1 or 3 octets (see text) 
exponent   as specified by length field 
modulus   remaining space 

而RSA公共密鑰是一個有點複雜 - 除了指數和模量,你需要用正確的OID as such (2nd answer)前綴它。

之後,該過程是有點粗糙:

  1. 獲取RRSIG記錄,以獲得簽名和密鑰標籤(以確定使用哪個密鑰)

  2. 使用來自公鑰正確的DNSKEY RR來驗證簽名。

還有一個過程描述here(在python)

+0

感謝第三個鏈接到其他SO帖子非常豐富。我也遇到了Python的實現,但我不明白它,最後一點定義如何確定它是否是一個有效的簽名是非常模糊的,PHP也有問題處理這樣長的數字,所以這就是原因我想在openssl庫中使用build,這應該能夠完成這項工作。你能幫我理解如何解析返回的RRSIG和它組成的人嗎? – Rabin