Криптографически сгенерированный адрес ( CGA ) — это адрес Интернет-протокола версии 6 (IPv6), который имеет идентификатор хоста, вычисленный с помощью криптографической хэш-функции . [1] Эта процедура представляет собой метод привязки открытого ключа подписи к адресу IPv6 в протоколе Secure Neighbor Discovery Protocol (SEND). [2]
Криптографически сгенерированный адрес — это адрес IPv6, идентификатор интерфейса которого был сгенерирован в соответствии с методом генерации CGA. Идентификатор интерфейса формируется из младших 64 бит адреса IPv6 и используется для идентификации сетевого интерфейса хоста в его подсети. Подсеть определяется старшими 64 битами, префиксом подсети.
Помимо открытого ключа, который должен быть привязан к CGA, метод генерации CGA принимает несколько других входных параметров, включая предопределенный префикс подсети. Эти параметры, наряду с другими параметрами, которые генерируются во время выполнения метода генерации CGA, образуют набор параметров, называемый структурой данных параметров CGA. Полный набор параметров CGA должен быть известен, чтобы иметь возможность проверить соответствующий CGA.
Структура данных параметров CGA состоит из:
modifier
: случайное 128-битное целое число без знака ;subnetPrefix
: 64-битный префикс, определяющий, к какой подсети принадлежит CGA;collCount
: 8-битное целое число без знака, которое должно быть равно 0, 1 или 2;publicKey
: открытый ключ как структура ASN.1 в кодировке DER типа SubjectPublicKeyInfo;extFields
: необязательное поле переменной длины (длина по умолчанию 0).Кроме того, параметр безопасности Sec
определяет устойчивость CGA к атакам методом подбора . Это 3-битное целое число без знака, которое может иметь любое значение от 0 до (включая) 7 и кодируется в трех крайних левых битах идентификатора интерфейса CGA. Чем выше значение Sec
, тем выше уровень безопасности, но и тем больше времени обычно требуется для генерации CGA. Для удобства Sec
предполагается, что промежуточные значения в приведенном ниже псевдокоде хранятся как 8-битные целые числа без знака, которые не могут иметь значение больше 7.
Следующий фрагмент псевдокода представляет метод генерации CGA, который используется для создания нового криптографически сгенерированного адреса.
1 процедура generateCGA( Sec , subnetPrefix , publicKey , extFields ): 2 модификатор := random(0x00000000000000000000000000000000000, // 16 октетов (128 бит) 3 0xffffffffffffffffffffffffffffffff) 4 5 метка1 : 6 concat := concatenate( modifier , 0x0000000000000000000, // 9 нулевых октетов 7 publicKey , extFields ) 8 9 дайджест := SHA1( concat )10 Hash2 := digest [0:14] // 14*8 = 112 крайних левых бит1112, если Sec ≠ 0 и Hash2 [0:2* Sec ] ≠ 0: // 2*Sec*8 = 16*Sec самые левые биты13 модификатор := модификатор + 114 перейти к метке115 конец если1617 collCount := 0x00 // 8-битное количество столкновений1819 метка2 :20 concat := concatenate( модификатор , subnetPrefix , collCount ,21 publicKey , extFields )2223 дайджест := SHA1( concat )24 Hash1 := digest [0:8] // 8*8 = 64 крайних левых бита2526 intID := Hash1 // Hash1 становится идентификатором интерфейса...27 intID [0] := intID [0] двоичный и 0x1c двоичный или ( Sec << 5) // ...после записи битов Sec и u/g2829 CGA := concatenate( subnetPrefix , intID ) // конкатенация для формирования CGA3031 если дубликат ( CGA ):32 collCount := collCount + 13334, если collCount = 3:35 прервать 36 закончить если3738 перейти к метке239 конец если4041 возвращает [ CGA , [ модификатор , subnetPrefix , collCount , publicKey , extFields ]]42 конец процедуры
Идентификатор интерфейса CGA в значительной степени формируется с помощью Hash1
, который берется из первых 64 бит переваренной структуры данных параметров CGA (строки 20–24). В строке 27 первые три бита перезаписываются значением Sec
, а зарезервированные биты «u» и «g» (седьмой и восьмой биты) устанавливаются в 0.
Параметр Sec
реализует расширение хеша, принудительно устанавливая первые 16 Sec
бит другого хеша, Hash2
, равными 0. Этот хеш является результатом переваренной структуры данных параметров CGA с subnetPrefix
и , collCount
по сути, установленными в 0. Выполняется поиск методом перебораHash2
для нахождения подходящего , увеличивая modifier
на 1 на каждой итерации (строки с 6 по 15). Поскольку больше бит должны быть равны 0 с более высоким Sec
значением, среднее время, необходимое для выполнения поиска, увеличивается экспоненциально со значением Sec
.
После объединения префикса подсети и сгенерированного идентификатора интерфейса для создания CGA может быть выполнено обнаружение дубликатов адресов . Если адрес уже используется, то счетчик столкновений collCount
увеличивается на 1 и генерируется новый идентификатор интерфейса (строки 20–39). Поскольку collCount
не используется при вычислении Hash2
, нет необходимости искать новый Hash2
при возникновении конфликта адресов. По той же причине subnetPrefix
не используется также , так что если префикс подсети адреса изменится, а открытый ключ хоста — нет, то тот же модификатор можно будет использовать повторно, и нет необходимости искать новый Hash2
.
В строке 41 возвращается CGA вместе со структурой данных параметров CGA.
Криптографически сгенерированный адрес используется для проверки того, что полученные подписанные сообщения были отправлены хостом, которому был назначен этот адрес. Это делается путем проверки того, что пара ключей, используемая для подписи, была привязана к CGA. Поскольку подлинность открытого ключа может быть проверена таким образом, нет необходимости в инфраструктуре открытого ключа. Однако, если сам хост также должен быть аутентифицирован, то сам CGA должен быть аутентифицирован заранее, поскольку привязанный открытый ключ не может быть доверенным, если адрес не является доверенным в таком случае (предполагая, что он не был проверен другими методами, кроме CGA).
Метод проверки CGA, при котором проверяется привязка открытого ключа к CGA, требует в качестве входных данных соответствующую структуру данных параметров CGA и может быть реализован следующим образом.
1 процедура verifyCGA( CGA , [ модификатор , subnetPrefix , collCount , publicKey , extFields ]): 2, если collCount > 2 или CGA [0:8] ≠ subnetPrefix : 3 вернуть ложь 4 конец если 5 6 concat := concatenate( модификатор , subnetPrefix , collCount , 7 publicKey , extFields ) 8 9 дайджест := SHA1( concat )10 Hash1 := digest [0:8] // 8*8 = 64 крайних левых бита11 Hash1 [0] := Hash1 [0] двоичный и 0x1c // игнорировать биты Sec и u/g1213 intID := CGA [8:16] // идентификатор интерфейса (64 крайних правых бита)14 intID [0] := intID [0] двоичный и 0x1c // игнорировать биты Sec и u/g1516, если Hash1 ≠ intID :17 возвращает ложь18 конец если1920 сек := CGA [8] >> 5 // извлечь сек из идентификатора интерфейса2122 concat := concatenate( modifier , 0x0000000000000000000, // 9 нулевых октетов23 publicKey , extFields )2425 дайджест := SHA1( concat )26 Hash2 := digest [0:14] // 14*8 = 112 крайних левых бит2728, если Sec ≠ 0 и Hash2 [0:2* Sec ] ≠ 0: // 2*Sec*8 = 16*Sec самые левые биты29 возвращает ложь30 конец если3132 return true // проверка прошла успешно33 конец процедуры
Метод начинается с проверки того, collCount
имеет ли структура данных CGA Parameters допустимое значение и subnetPrefix
совпадает ли эта же структура данных с префиксом подсети CGA (в строке 2). Это делается из соображений безопасности.
С 6 по 18 строку Hash1
вычисляется из структуры данных параметров CGA (которая включает открытый ключ и префикс подсети), и соответствующие биты сравниваются с битами идентификатора интерфейса CGA. В этом случае это делается путем установки первых трех бит ( Sec
) и седьмого и восьмого бита (биты "u" и "g") обоих Hash1
и идентификатора интерфейса в 0 в строках 11 и 14 для простого сравнения.
После извлечения Sec
из идентификатора интерфейса CGA Hash2
вычисляется и первые 16 Sec
бит хэша сравниваются с 0 (строки 22–30). Если все проверки пройдены успешно, то открытый ключ подтверждается на предмет привязки к этому CGA (т. е. является действительным для него).
Чтобы злоумышленник заставил клиента поверить, что он получил действительное сообщение от определенного CGA, который не принадлежит злоумышленнику, злоумышленник должен найти коллизию хэшей для соответствующих битов Hash1
и , Hash2
выполнив атаку методом подбора . Если злоумышленник находит набор параметров CGA (включая открытый ключ, для которого злоумышленник знает закрытый ключ), который может быть использован для генерации того же CGA, что и целевой CGA, то злоумышленник может выдать себя за хост, который на самом деле владеет CGA, не будучи обнаруженным (за исключением, возможно, случаев, когда клиент уже связывался с хостом и замечает, что открытый ключ изменился, а CGA — нет).
Из 64 бит в Hash1
, только 59 используются в идентификаторе интерфейса, так как 5 бит перезаписываются. Для CGA с Sec
равным 0 это означает, что стоимость поиска набора параметров CGA, которые дают желаемые 59 бит, приблизительно равна (в нотации большого O ). Однако большее значение увеличивает эту стоимость в раз, так как первые 16 бит затем становятся релевантными (т. е. оно реализует расширение хеша, требуя, чтобы эти биты были равны 0). В процессе генерации CGA стоимость генерации адреса увеличивается в раз, зависящий от значения , но стоимость использования и проверки CGA остается постоянной.Sec
Sec
Hash2
Sec
Поскольку Sec
это не часть структуры данных параметров CGA, а часть самого адреса, злоумышленник не может использовать Sec
значение, меньшее, чем целевой адрес (например, 0), в попытке пропустить (или уменьшить) атаку методом подбора на Hash2
. Это, в частности, даст CGA, отличный от целевого CGA, поскольку по крайней мере один из трех крайних левых битов идентификатора интерфейса не совпадет. Если целевое Sec
значение все равно записано в идентификатор интерфейса, то Hash2
(почти наверняка) будет обнаружено отсутствие необходимого количества крайних левых нулевых битов во время процесса проверки.
В процессе генерации CGA маловероятно, что произойдет три коллизии адресов. Если дублирующий адрес будет обнаружен в третий раз, то это, скорее всего, будет связано с ошибкой конфигурации или реализации или атакой типа «отказ в обслуживании» . По этой причине количество допустимых значений для collCount
ограничено диапазоном от 0 до 2. Этот параметр должен быть проверен на соответствие этому диапазону в процессе проверки CGA, чтобы не допустить его эксплуатации злоумышленником и попытки перебрать все разные значения без необходимости выполнять еще один перебор для Hash2
каждого раза, когда пробуется другое значение.
Включая префикс подсети в операцию дайджеста, которая приводит к Hash1
, можно предотвратить возможность использования злоумышленником одной предварительно вычисленной базы данных для атаки адресов с разными префиксами подсети. Проверяющий также может быть уверен, что открытый ключ был привязан к этому точному адресу, а не к адресу с тем же идентификатором интерфейса, но другим префиксом подсети. Поскольку спецификация CGA предписывает использовать subnetPrefix
из структуры данных параметров CGA для операций дайджеста, необходимо проверить, что он соответствует префиксу подсети CGA во время процесса проверки CGA.