使用openssl使用PHP验证RRSIG

时间:2017-05-09 11:14:38

标签: php php-openssl dnssec

我正在尝试进行RRSIG验证,我正在尝试在PHP中使用openssl lib。但是我将公钥传递给openssl_verify函数时遇到了问题。

这是一个基本代码, 使用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');

2 个答案:

答案 0 :(得分:2)

简答:

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

长答案:

您无法加载KEY数据的原因是因为它的格式略有不同。根据{{​​3}}:

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

虽然RSA公钥有点复杂 - 除了指数和模数之外,您需要在前面加上正确的OID rfc3110

之后这个过程有点粗糙:

  1. 获取RRSIG记录以获取签名和密钥标记(以确定使用哪个密钥)

  2. 使用正确的DNSKEY RR中的公钥来验证签名。

  3. 还有一个描述as such (2nd answer)(在python中)

    的过程

答案 1 :(得分:0)

PHP_EOL是特定于平台的,不确定您正在测试此代码的平台,但请尝试明确地用'\n'替换常量。看看是否有帮助。