Построение части RDATA DNSKEY RR

Я нахожусь в процессе завершения плагина Регистратора домена для биллинговой системы (которая в этом случае также управляет подготовкой домена), и последний бит связан с реализацией поддержки DNSSEC.

Биллинговая система отправляет в мой плагин PHP следующие данные, относящиеся к SAMPLE DNSSEC:

'dnsSecInfo' =>
array (
0 =>
array (
'keyAlg' => 5,
'digestAlg' => 1,
'digest' => '1d181b34061ee98088b7a9e6db6e41a130674df0',
'key' => 'AwEAAaqZeENizOE6uvpDtIfQBB26YebvRdZA/ZjXjKLZdMmMK641sBIvho+yrTveIYclM+8lEVHiq64MY8R2G1IPmKDKXG26rM7NVE0Qx1KL2wRVbRrduRdBmKgJo3XQ3niueviKYXXmeVIO3EhrJsCq272Tm3DaDvng/M7uw1vDnanR2pYNcxI08fZOA6PLGDoUWlDNLGAHHkCvfdWUktVt1DA0GtL/qE/WUgxK6hJyeaXXb0+yq3qCMZh48WgluMFib54D0GN3PI3ZZvBMblAZHmFGqgyVwtPKEimXm/VREe2QtZy3cRgPbfOuiQi8gRhzO+/If8Wi9YnyLovjdsSjRsE=',
),
),

RFC 4034 имеет следующее:

2.1.  DNSKEY RDATA Wire Format

The RDATA for a DNSKEY RR consists of a 2 octet Flags Field, a 1
octet Protocol Field, a 1 octet Algorithm Field, and the Public Key
Field.

1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|              Flags            |    Protocol   |   Algorithm   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/                                                               /
/                            Public Key                         /
/                                                               /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Приложение B того же протокола:

The input is the wire
format of the RDATA portion of the DNSKEY RR.
.....
unsigned int
keytag (
unsigned char key[],  /* the RDATA part of the DNSKEY RR */
unsigned int keysize  /* the RDLENGTH */
)
{
unsigned long ac;     /* assumed to be 32 bits or larger */
int i;                /* loop index */

for ( ac = 0, i = 0; i < keysize; ++i )
ac += (i & 1) ? key[i] : key[i] << 8;
ac += (ac >> 16) & 0xFFFF;
return ac & 0xFFFF;
}

Реестр, где регистрируется домен, занимает 4 обязательных поля:

  1. Keytag
  2. Алгоритм (считается равным keyAlg во входных данных плагина)
  3. Тип дайджеста (я считаю, что он называется digestAlg во входных данных плагина)
  4. Дайджест (так же, как дайджест, вероятно)

Другой Необязательный поля: флаги, протокол, алгоритм, открытый ключ (который является «ключом» в плагине …)

Теперь я заблудился …
Как мне реализовать вышеупомянутую функцию C в PHP?

  1. Как мне построить «DNSKEY RDATA», который является key массив символов? (Я думаю, что флаги
    октеты являются значениями по умолчанию, такими как 0, 256 или 257 еще не уверены), затем
    Октет протокола — это значение keyAlg 5 в этом примере, за которым следует
    Октет алгоритма, который всегда равен 3, и, наконец, ключевой октет
    ключ. Это предположение правильно ??)
  2. Является ли массив символов ключа [] RDATA двоичным массивом? или аськи чарс?
    (имеется в виду, что после создания мне не нужно преобразовывать его в двоичные биты
    первый?)
  3. Что такое & 0xFFFF цель в алгоритме? Что такое эквивалент PHP? Я склонен думать, что это почти то же самое, так как PHP основан на C в синтаксисе … но без правильных примеров ввода / вывода будет трудно убедиться, что я все понял правильно …

0

Решение

Ваш вопрос не очень понятен. Вы строите систему регистратора или что-то, что соединяется с регистратором?
Также ваш заголовок говорит о построении RDATA DNSKEY, но тогда весь ваш вопрос касается вычисления keyid / keytag, который все равно не публикуется с записью DNSKEY (только публикуется с записями RRSIG, но такими инструментами, как dig можно пересчитать его, чтобы отобразить его как комментарий, чтобы помочь вам при просмотре записей DNSKEY).

В любом случае вам не нужно иметь дело с форматом передачи данных DNSSEC. В первом случае (система регистратора) вы взаимодействуете с реестром, как правило, с EPP, который имеет специальное расширение для данных DNSSEC, называемое secDNS. Увидеть RFC5910

Теперь что касается самого DNSSEC. Он использует криптографию, поэтому лучше не пытаться переделывать вещи вручную. Кажется, PHP имеет Net_DNS2 это могло бы помочь.

Но то, что я не понимаю, это то, почему вы должны испортить ценности. Если вы являетесь регистратором, вы передаете в реестр значения, которые дали вам ваши клиенты; Вы можете немного проверить их синтаксис, но, кроме того, вы просто передаете их. Если вы предоставляете данные регистратору в качестве клиента, вы снова откуда-то получили эти данные, я не понимаю, почему вы должны действовать в соответствии с ними.

Теперь вы говорите о реестре, так что пока я представлю, что вы регистратор. Начните с чтения RFC5910. Вы увидите, что есть два интерфейса, а на самом деле 3 случая, в порядке от наиболее часто используемого сейчас до менее часто:

  1. dsData интерфейс, в котором вы, как регистратор, даете реестру запись DS в основном для публикации в реестре; эти данные (на самом деле 4 поля, вы перечисляете их в первом наборе) составлены из ключа, который вы или хостинговая компания опубликуете в доменном файле зоны как запись DNSKEY.
  2. keyData интерфейс, опять же с 4 полями, но не такой, как у 4 предыдущих (есть в вашем втором наборе или структуре PHP в верхней части вашего поста), где на самом деле вы отправляете ключу реестра (его публичную часть), из которого реестр будет вычислять саму запись DS
  3. и смешанный случай, когда это в основном dsData с keyData внутри, что означает, что вы отправляете как DS для публикации, так и связанный ключ, причем этот ключ бесполезен, но реестр может повторить вычисления DS для проверки, исходя из ключа.

Если вы прочитаете RFC, у вас будут объяснения по 2 наборам из 4 полей и их значения.

Для некоторых из них вы можете использовать только несколько отдельных значений:

Что касается ваших конкретных вопросов, которые, кажется, вы пытаетесь вычислить keyID / keytag из содержимого ключа (удивительно, что было обнаружено, что этот алгоритм имеет недостатки, но в любом случае), как я уже говорил ранее, вы не должны пытаться повторить это самостоятельно. Если возможно, попытайтесь найти библиотеку PHP, которая сделает это за вас, или, по крайней мере, используйте существующие инструменты, но это зависит от того, как генерируются ваши ключи, откуда вы их получаете и т.д.
Смотрите, например, этот инструмент: https://linux.die.net/man/8/dnssec-keygen

В противном случае у вас есть этот код: https://www.v13.gr/blog/?p=239
Это на Python, но вы можете извлечь версию PHP из него. Помните, что метка ключа зависит только от содержимого ключа, где значение хеш-функции DS зависит как от ключа, так и от имени домена (поэтому даже если вы используете один и тот же ключ для разных доменных имен, значение DS будет отличаться).

Так что для вашего 1) + 2) примерно 4 поля, необходимые для keyData интерфейс:

  • flag: либо 256, либо 257 в зависимости от того, используется ли ключ в качестве KSK или ZSK; в качестве регистратора, передающего значения ключей в реестры, это должны быть только значения KSK, поэтому значение 257.
  • протокол: всегда значение 3, см. 2.1.2. из RFC4034
  • Алгоритм: из Приложения 1 того же RFC, который в основном является первой ссылкой из двух вышеупомянутых iana.org
  • вход алгоритма — это значение DNSKEY RDATA, как написано в разделе 2.2: «Поле открытого ключа ДОЛЖНО быть представлено как кодировка Base64 открытого ключа.», так что это список символов.

Что касается 3): делать & 0xFFFF означает брать 16-битные младшие разряды (обычно самые правые 16-битные, когда вы их записываете), потому что & является логическим И, и 0xFFFF равен 2 ^ 16 — 1 (65535), то есть 16 битов установлены на значение 1. Сказано, что в противном случае, если конечное значение превышает 65535, мы сохраняем только его часть с этой операцией, так как тэг ключа определяется как 16-битное значение.

Кстати, вы можете использовать dnssec-keygen Команда для создания ключей и их ключей, чтобы проверить свой собственный алгоритм.

dnssec-keygen -a RSASHA256 -b 2048 test1 будет производить:

Generating key pair.......+++ ............................+++
Ktest1.+008+05433

В сгенерированном имени файла 008 это алгоритм (от RSASHA256) и 05433 вычисляется keyId (keytag). Если вы посмотрите на файл вычисляется в окончании .key у вас есть полная запись DNSKEY с ключом, закодированным как Base64, согласно спецификации (которая является входом алгоритма для вычисления keyid).

Я надеюсь, что вы найдете хотя бы некоторые полезные идеи в вышеприведенном материале, но я боюсь, что не понял ваш вопрос достаточно хорошо, чтобы быть более конкретным.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]