Подтвердите RRSIG с помощью PHP, используя openssl

Я пытаюсь выполнить проверку RRSIG, я пытаюсь использовать библиотеку openssl в PHP. Но у меня проблема с передачей открытого ключа функции openssl_verify.

Это базовый код, использующий библиотеку Net/DNS2 для выполнения DNS-запроса с параметром DNSSEC. и получите 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');

person Rabin    schedule 09.05.2017    source источник
comment
Вы смотрели @ php.net/manual/en/function.openssl-verify. php. У них есть хорошие примеры   -  person E_p    schedule 16.05.2017
comment
Да, я сделал @E_p, моя проблема заключается в том, как передать ключ, который я получаю из DNS-запроса, в функцию, независимо от того, какой формат я пытаюсь использовать, я получаю сообщение об ошибке о неправильном формате ключа.   -  person Rabin    schedule 16.05.2017
comment
Возможно ли, что когда вы получаете ключ, в нем есть лишние пробелы или что-то еще, что может создать эту проблему?   -  person E_p    schedule 16.05.2017
comment
@E_p, я не вижу лишних пробелов, проверено путем печати ключа и канала через xxd , выглядят одинаково. Другой вариант заключается в том, что ключ необходимо обработать перед передачей его функции (возможно, удалить некоторые байты).   -  person Rabin    schedule 17.05.2017


Ответы (2)


Короткий ответ:

Если вам просто нужна возможность в PHP, вы можете просто использовать https://github.com/metaregistrar/php-dnssec-validator .

Длинный ответ:

Причина, по которой вы не можете загрузить данные KEY, заключается в том, что они имеют немного другой формат. Согласно rfc3110:

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

Принимая во внимание, что открытые ключи RSA немного сложнее - помимо показателя степени и модуля, вам нужно добавить префикс с правильным OID как таковое (2-й ответ).

После этого процесс немного корявый:

  1. Получите запись RRSIG, чтобы получить подпись и тег ключа (чтобы определить, какой ключ использовать)

  2. Используйте открытые ключи из правильной DNSKEY RR для проверки подписи.

Также описан процесс здесь (на python)

person aljo f    schedule 21.05.2017
comment
Спасибо, третья ссылка на другой пост SO была очень информативной. также я столкнулся с реализацией python, но я ее не понял, последний бит, который определяет, как вы можете определить, была ли это действительной подписью, очень расплывчатый, также у PHP есть проблемы с работой с такими длинными числами, так что это причина Я хотел использовать сборку в библиотеке openssl, которая должна выполнять эту работу. Не могли бы вы помочь мне понять, как препарировать возвращенный RRSIG и кто его составил? - person Rabin; 21.05.2017

PHP_EOL зависит от платформы, не уверен, на какой платформе вы тестируете этот код, но попробуйте явно заменить константу на '\n'. Посмотрите, поможет ли это.

person Jeremy Giberson    schedule 16.05.2017
comment
Никакой разницы не сделал. - person Rabin; 17.05.2017