Adres wygenerowany kryptograficznie
Adres wygenerowany kryptograficznie ( CGA ) to adres protokołu internetowego w wersji 6 (IPv6), który ma identyfikator hosta obliczony na podstawie kryptograficznej funkcji skrótu . Ta procedura jest metodą powiązania publicznego klucza podpisu z adresem IPv6 w protokole Secure Neighbor Discovery Protocol (SEND).
Charakterystyka
Adres wygenerowany kryptograficznie to adres IPv6, którego identyfikator interfejsu został wygenerowany zgodnie z metodą generowania CGA. Identyfikator interfejsu składa się z najmniej znaczących 64 bitów adresu IPv6 i służy do identyfikacji interfejsu sieciowego hosta w jego podsieci. Podsieć jest określana przez najbardziej znaczące 64 bity, prefiks podsieci.
Format adresu IPv4 bity pole prefiks podsieci identyfikator interfejsu
Oprócz klucza publicznego, który ma być powiązany z CGA, metoda generowania CGA pobiera kilka innych parametrów wejściowych, w tym prefiks prefiksu podsieci. Parametry te wraz z innymi parametrami, które są generowane podczas wykonywania metody generowania CGA, tworzą zestaw parametrów zwany strukturą danych CGA Parameters. Pełny zestaw parametrów CGA musi być znany, aby móc zweryfikować odpowiedni CGA.
Struktura danych parametrów CGA składa się z:
-
modyfikator
: losowa 128-bitowa liczba całkowita bez znaku ; -
subnetPrefix
: 64-bitowy prefiks określający, do której podsieci należy CGA; -
collCount
: 8-bitowa liczba całkowita bez znaku, która musi wynosić 0, 1 lub 2; -
publicKey
: klucz publiczny jako zakodowana w DER struktura ASN.1 typu SubjectPublicKeyInfo; -
extFields
: opcjonalne pole o zmiennej długości (domyślna długość 0).
Dodatkowo parametr bezpieczeństwa Sec
określa siłę CGA przeciwko atakom typu brute-force . Jest to 3-bitowa liczba całkowita bez znaku, która może mieć dowolną wartość od 0 do (włącznie) 7 i jest zakodowana w trzech skrajnych lewych bitach identyfikatora interfejsu CGA. Im wyższa wartość Sec
, tym wyższy poziom bezpieczeństwa, ale także generalnie dłużej trwa generowanie CGA. Dla wygody przyjmuje się, że pośrednie Sec
w poniższym pseudokodzie są przechowywane jako 8-bitowe liczby całkowite bez znaku, które nie mogą mieć wartości większej niż 7.
Metoda generowania CGA
Poniższy fragment pseudokodu reprezentuje metodę generowania CGA, która jest używana do tworzenia nowego adresu wygenerowanego kryptograficznie.
1 procedura generujCGA( Sec , subnetPrefix , publicKey , extFields ): 2 modyfikator := random(0x000000000000000000000000000000000, // 16 oktetów (128 bitów) 3 0xffffffffffffffffffffffffffffffff) 4 5 label1 : 6 conca t := concatenate( modyfikator , 0x000000000000000000, // 9 zero octets 7 publicKey , extFields ) 8 9 digest := SHA1( concat ) 10 Hash2 := digest [0:14] // 14*8 = 112 skrajnych lewych bitów 11 12 if Sec ≠ 0 i Hash2 [0:2* Sec ] ≠ 0: // 2*Sec*8 = 16*Sek skrajne lewe bity 13 modyfikator := modyfikator + 1 14 goto label1 15 end if 16 17 collCount := 0x00 // 8-bitowa liczba kolizji 18 19 label2 : 20 concat := concatenate ( modyfikator , subnetPrefix , collCount , 21 publicKey , extFields ) 22 23 digest := SHA1( concat ) 24 Hash1 := digest [0:8] // 8*8 = 64 skrajne lewe bity 25 26 intID := Hash1 // Hash1 staje się identyfikator interfejsu... 27 intID [0] := intID [0] binarny i 0x1c binarny lub ( Sec << 5) // ...po zapisaniu bitów Sec i u/g 28 29 CGA := concatenate( subnetPrefix , intID ) // konkatenacja w celu utworzenia CGA 30 31 if duplikat( CGA ): 32 collCount := collCount + 1 33 34 if collCount = 3: 35 abort 36 end if 37 38 goto label2 39 end if 40 41 return [ CGA , [ modyfikator , subnetPrefix , collCount , publicKey , extFields ]] 42 procedura końcowa
Identyfikator interfejsu CGA jest w dużej mierze tworzony przez Hash1
, który jest pobierany z pierwszych 64 bitów przetworzonej struktury danych CGA Parameters (linie od 20 do 24). W linii 27 pierwsze trzy bity są nadpisywane przez Sec
, a zarezerwowane bity „u” i „g” (siódmy i ósmy bit) są ustawiane na 0.
Parametr Sec
implementuje rozszerzenie skrótu, wymuszając, aby pierwsze 16 bitów Sec
innego skrótu, Hash2
, wynosiło 0. Ten skrót jest wynikiem przetworzonej struktury danych CGA Parameters z subnetPrefix
i collCount
zasadniczo ustawionymi na 0. Brute-force search jest wykonywane w celu znalezienia odpowiedniego Hash2
, zwiększając modyfikator
o 1 w każdej iteracji (linie od 6 do 15). Ponieważ więcej bitów musi mieć wartość 0 przy wyższej Sec
, średni czas potrzebny do wykonania wyszukiwania rośnie wykładniczo wraz z wartością Sec
.
Po połączeniu prefiksu podsieci i wygenerowanego identyfikatora interfejsu w celu utworzenia CGA można przeprowadzić wykrywanie zduplikowanych adresów . Jeśli adres jest już w użyciu, licznik kolizji colCount
jest zwiększany o 1 i generowany jest nowy identyfikator interfejsu (linie od 20 do 39). Ponieważ collCount
nie jest używany do obliczania Hash2
, nie ma potrzeby wyszukiwania nowego Hash2
w przypadku wystąpienia kolizji adresów. Z podobnego powodu subnetPrefix
nie jest również używany, więc jeśli zmieni się prefiks podsieci adresu, ale klucz publiczny hosta nie, to ten sam modyfikator może zostać ponownie użyty i nie ma potrzeby wyszukiwania nowego Hash2
.
W linii 41 zwracany jest CGA wraz ze strukturą danych CGA Parameters.
Metoda weryfikacji CGA
Adres wygenerowany kryptograficznie służy do sprawdzenia, czy otrzymane podpisane wiadomości zostały wysłane przez hosta, do którego przypisano ten adres. Odbywa się to poprzez sprawdzenie, czy para kluczy używana do podpisywania została powiązana z CGA. Ponieważ w ten sposób można zweryfikować autentyczność klucza publicznego, nie ma potrzeby stosowania infrastruktury klucza publicznego. Jeśli jednak wymagane jest również uwierzytelnienie samego hosta, to samo CGA musi zostać wcześniej uwierzytelnione, ponieważ powiązanemu kluczowi publicznemu nie można ufać, jeśli w takim przypadku adres nie jest zaufany (zakładając, że nie został zweryfikowany przez inne metody niż CGA).
Sposób weryfikacji CGA, w którym weryfikuje się, czy klucz publiczny jest powiązany z CGA, wymaga odpowiedniej struktury danych parametrów CGA jako danych wejściowych i może być zaimplementowany w następujący sposób.
1 procedura validCGA( CGA , [ modyfikator , subnetPrefix , collCount , publicKey , extFields ]): 2 if collCount > 2 lub CGA [0:8] ≠ subnetPrefix : 3 return false 4 end if 5 6 concat := concatenate( modyfikator , subnetPrefix , collCount , 7 publicKey , extFields ) 8 9 Digest := SHA1( concat ) 10 Hash1 := Digest [0:8] // 8*8 = 64 skrajne lewe bity 11 Hash1 [0] := Hash1 [0] binarne i 0x1c // ignoruj bity Sec i u/g 12 13 intID := CGA [8:16] // identyfikator interfejsu (64 skrajne prawe bity) 14 intID [0] := intID [0] binarne i 0x1c // ignoruj Sec i u/ g bity 15 16 if Hash1 ≠ intID : 17 return false 18 end if 19 20 Sec := CGA [8] >> 5 // wyodrębnij Sec z identyfikatora interfejsu 21 22 concat := concatenate( modyfikator , 0x00000000000000000, // 9 oktetów zero 23 publicKey , extFields ) 24 25 digest := SHA1( concat ) 26 Hash2 := digest [0:14] // 14*8 = 112 skrajnych lewych bitów 27 28 if Sec ≠ 0 i Hash2 [0:2* Sec ] ≠ 0 : // 2*Sek*8 = 16*Sek. skrajne lewe bity 29 return false 30 end if 31 32 return true // weryfikacja powiodła się 33 end procedura
Metoda rozpoczyna się od sprawdzenia, czy collCount
ze struktury danych CGA Parameters ma poprawną wartość i czy subnetPrefix
z tej samej struktury danych pasuje do prefiksu podsieci CGA (w linii 2). Odbywa się to ze względów bezpieczeństwa .
Od linii 6 do 18, Hash1
jest obliczany ze struktury danych CGA Parameters (która zawiera klucz publiczny i prefiks podsieci), a odpowiednie bity są porównywane z bitami identyfikatora interfejsu CGA. W tym przypadku odbywa się to poprzez ustawienie pierwszych trzech bitów ( Sec
) oraz siódmego i ósmego bitu (bity „u” i „g”) zarówno Hash1
, jak i identyfikatora interfejsu na 0 w liniach 11 i 14 dla łatwego porównania.
Po wydobyciu Sec
z identyfikatora interfejsu CGA, obliczany jest Hash2
i pierwsze 16 razy Sec
bitów skrótu jest porównywane z 0 (linie od 22 do 30). Jeśli wszystkie kontrole zakończą się pomyślnie, klucz publiczny został zweryfikowany jako powiązany (tj. ważny dla) tego CGA.
Bezpieczeństwo
Aby atakujący mógł przekonać klienta , że otrzymał prawidłową wiadomość od określonego CGA, który nie jest własnością atakującego, atakujący musi znaleźć kolizję skrótów dla odpowiednich bitów Hash1
i Hash2
, przeprowadzając atak brute-force . Jeśli atakujący znajdzie zestaw parametrów CGA (w tym klucz publiczny, dla którego atakujący zna klucz prywatny), których można użyć do wygenerowania tego samego CGA, co docelowy CGA, wówczas atakujący może podszyć się pod hosta, który faktycznie jest właścicielem CGA bez wykrycie (z wyjątkiem być może sytuacji, gdy klient kontaktował się wcześniej z hostem i zauważył, że klucz publiczny się zmienił, ale CGA nie).
Z 64 bitów Hash1
tylko 59 jest używanych w identyfikatorze interfejsu, ponieważ 5 bitów jest zastępowanych. W przypadku CGA z Sec równym 0 oznacza to, że koszt
zestawu parametrów CGA, które dają pożądane 59 bitów, wynosi w dużym O notacja ). Większa wartość Sec
zwiększa jednak ten koszt o współczynnik O , ponieważ pierwsze 16 razy Sec
bity Hash2
stają się wtedy istotne (tj. implementuje rozszerzenie hash, żądając, aby te bity były równe 0). W procesie generowania CGA koszt wygenerowania adresu zwiększa się o ten sam współczynnik w zależności od wartości Sec
, ale koszt użycia i weryfikacji CGA pozostaje stały.
Ponieważ Sec
nie jest częścią struktury danych CGA Parameters, ale samego adresu, osoba atakująca nie może użyć wartości Sec
mniejszej niż wartość adresu docelowego (np. 0) w celu pominięcia (lub zmniejszenia) ataku brute-force na Hash2
. Dałoby to mianowicie inny CGA niż docelowy CGA, ponieważ co najmniej jeden z trzech skrajnych lewych bitów identyfikatora interfejsu nie byłby zgodny. Jeśli i tak docelowa Sec
zostanie zapisana w identyfikatorze interfejsu, to podczas procesu weryfikacji Hash2
(prawie na pewno) okaże się, że brakuje wymaganej ilości skrajnych lewych bitów 0.
Podczas procesu generowania CGA jest bardzo mało prawdopodobne, że wystąpią trzy kolizje adresów. Jeśli zduplikowany adres zostałby wykryty po raz trzeci, najprawdopodobniej byłoby to spowodowane błędem konfiguracji lub implementacji albo atakiem typu „ odmowa usługi” . Z tego powodu liczba prawidłowych wartości dla colCount
jest ograniczona do zakresu od 0 do 2. Ten parametr musi zostać zweryfikowany, aby mieścił się w tym zakresie podczas procesu weryfikacji CGA, aby uniemożliwić atakującemu wykorzystanie go i wypróbowanie wszystkich różnych wartości bez konieczności wykonywania kolejnego brutalnego wyszukiwania Hash2
za każdym razem, gdy próbowana jest inna wartość.
Włączając prefiks podsieci do operacji skrótu, której wynikiem jest Hash1
, można zapobiec temu, że osoba atakująca może użyć jednej wstępnie obliczonej bazy danych do zaatakowania adresów z różnymi prefiksami podsieci. Weryfikator może również mieć pewność, że klucz publiczny został powiązany dokładnie z tym adresem, a nie z adresem z tym samym identyfikatorem interfejsu, ale z innym prefiksem podsieci. Ponieważ specyfikacja CGA zaleca używanie prefiksu podsieci
ze struktury danych CGA Parameters dla operacji skrótu, należy sprawdzić, czy jest on zgodny z prefiksem podsieci CGA podczas procesu weryfikacji CGA.