как проанализировать домен v3 onion

#php #tor

#php #tor

Вопрос:

Я пытаюсь выяснить, как я могу определить или программно извлечь значения открытого ключа, контрольной суммы и версии из домена v3 onion. Желательно на php.

Спецификация домена v3 onion изложена здесь: https://github.com/torproject/torspec/blob/main/rend-spec-v3.txt

Особенно интересует раздел 4.3.6

    The onion address of a hidden service includes its identity public key, a
   version field and a basic checksum. All this information is then base32
   encoded as shown below:

     onion_address = base32(PUBKEY | CHECKSUM | VERSION)   ".onion"
     CHECKSUM = H(".onion checksum" | PUBKEY | VERSION)[:2]

     where:
       - PUBKEY is the 32 bytes ed25519 master pubkey of the hidden service.
       - VERSION is a one byte version field (default value 'x03')
       - ".onion checksum" is a constant string
       - CHECKSUM is truncated to two bytes before inserting it in onion address

  Here are a few example addresses:

       pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion
       sp3k262uwy4r2k3ycr5awluarykdpag6a7y33jxop4cs2lu5uz5sseqd.onion
       xa4r2iadxm55fbnqgwwi5mymqdcofiu3w6rpbtqn7b2dyn7mgwj64jyd.onion
 

Если мы возьмем первый пример домена: pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion

если мы отбросим .onion суффикс, который должен оставить нам строку в кодировке base32 pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd .

Я предполагаю, что открытый ключ — это первые 32 байта декодированной строки base32? Я выполнил декодирование base32 здесь https://dencode.com/en/string?v=pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscrydamp;oe=UTF-8

Не уверен, что я на правильном пути, но как мне определить контрольную сумму и компоненты версии из этого?

Приведенный ниже php, похоже, работает с онлайн-декодером base32

     $onionUrl = "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion";

    //remove suffix
    $domain = str_replace(".onion", "", $onionUrl);

    //base32 decode
    $decoded = Base32::decode($domain);
    echo $decoded."<br>";
 

Комментарии:

1. Кажется, вы на правильном пути. Первые 32 байта — это открытый ключ, последний байт — это версия, все остальное — контрольная сумма.

2. я немного сбит с толку, потому что в нем указано значение по умолчанию для последнего байта (версии) 'x03' , но я не понимаю, как я могу получить это из последнего байта.

3. после декодирования base32 последний байт представляет собой квадрат, подобный символу utf8 — нужно ли это как-то преобразовать, чтобы получить версию?

Ответ №1:

Я понял это. Где $lastByte последний байт или символ декодированной строки base32. Использование bin2hex($lastByte) или unpack("H*", $lastByte) оба вернули значение 03 , которое согласуется с документацией о том, что версия по умолчанию равна 3.