Adresy URL i haszowanie

Ten dokument dotyczy tej metody: Update API (v4): fullHashes.find.

Opis

Listy Bezpiecznego przeglądania składają się z szyfrów SHA256 o zmiennej długości (patrz Lista zawartości). Aby sprawdzić adres URL na liście Bezpiecznego przeglądania (lokalnie lub na serwerze), klient musi najpierw obliczyć prefiks skrótu tego adresu URL.

Aby obliczyć prefiks skrótu adresu URL, wykonaj te czynności:

  1. Utwórz kanoniczny adres URL (patrz Konwertowanie kanoniczne).
  2. Utwórz wyrażenia sufiksu/prefiksu dla adresu URL (patrz wyrażenia sufiksu/prefiksu).
  3. Obliczaj hasz pełnej długości dla każdego sufiksu/prefiksu (patrz Obliczanie haszowania).
  4. Oblicz prefiks skrótu dla każdego haszu pełnej długości (patrz Obliczanie prefiksów haszowania).

Pamiętaj, że te czynności odzwierciedlają proces, którego serwer Bezpiecznego przeglądania używa do obsługi list Bezpiecznego przeglądania.

Konwertowanie kanoniczne

Na początek zakładamy, że klient przeanalizował adres URL i uznał go za prawidłowy zgodnie ze standardem RFC 2396. Jeśli adres URL zawiera umiędzynarodowioną nazwę domeny (IDN), klient powinien przekonwertować adres URL na reprezentację ASCII Punycode. Adres URL musi zawierać komponent ścieżki, czyli musi mieć na końcu ukośnik („http://google.com/”).

Najpierw usuń z adresu URL znaki tabulacji (0x09), CR (0x0d) i LF (0x0a). Nie usuwaj sekwencji zmiany znaczenia tych znaków (np. „%0a”).

Po drugie, jeśli adres URL kończy się fragmentem, usuń go. Na przykład skróć „http://google.com/#frag” do „http://google.com/”.

Po trzecie, wielokrotnie powtarzaj znaczenie zmiany znaczenia w adresie URL, aż nie będzie już żadnych znaków zmiany znaczenia.

Aby skonwertować nazwę hosta do postaci kanonicznej:

Wyodrębnij nazwę hosta z adresu URL, a następnie:

  1. Usuń wszystkie początkowe i końcowe kropki.
  2. Zastąp następujące po sobie kropki pojedynczą kropką.
  3. Jeśli nazwę hosta można przetworzyć jako adres IP, znormalizuj ją do wartości dziesiętnych oddzielonych kropkami. Klient powinien obsługiwać wszelkie zgodne z prawem kodowanie adresów IP, w tym ósemkowe, szesnastkowe i mniej niż 4 komponenty.
  4. Używaj tylko małych liter.

Aby skonwertować ścieżkę do postaci kanonicznej:

  1. Rozwiąż problemy z sekwencjami „/../” i „/./” w ścieżce, zastępując „/./” znakiem „/” oraz usuwając „/../” wraz z poprzednim komponentem ścieżki.
  2. Zastąp całe kolejne ukośniki pojedynczym ukośnikiem.

Nie stosuj tych przekształceń kanonicznych ścieżek do parametrów zapytania.

W adresie URL użyj znaku zmiany znaczenia procent w stosunku do wszystkich znaków <= ASCII 32, >= 127, „#” lub „%”. Znaki szesnastkowe powinny być pisane wielkimi literami.

Poniżej znajdziesz testy, które pomagają zweryfikować implementację wyboru strony kanonicznej.

Canonicalize("http://host/%25%32%35") = "http://host/%25";
Canonicalize("http://host/%25%32%35%25%32%35") = "http://host/%25%25";
Canonicalize("http://host/%2525252525252525") = "http://host/%25";
Canonicalize("http://host/asdf%25%32%35asd") = "http://host/asdf%25asd";
Canonicalize("http://host/%%%25%32%35asd%%") = "http://host/%25%25%25asd%25%25";
Canonicalize("http://www.google.com/") = "http://www.google.com/";
Canonicalize("http://%31%36%38%2e%31%38%38%2e%39%39%2e%32%36/%2E%73%65%63%75%72%65/%77%77%77%2E%65%62%61%79%2E%63%6F%6D/") = "http://168.188.99.26/.secure/www.ebay.com/";
Canonicalize("http://195.127.0.11/uploads/%20%20%20%20/.verify/.eBaysecure=updateuserdataxplimnbqmn-xplmvalidateinfoswqpcmlx=hgplmcx/") = "http://195.127.0.11/uploads/%20%20%20%20/.verify/.eBaysecure=updateuserdataxplimnbqmn-xplmvalidateinfoswqpcmlx=hgplmcx/";
Canonicalize("http://host%23.com/%257Ea%2521b%2540c%2523d%2524e%25f%255E00%252611%252A22%252833%252944_55%252B") = "http://host%23.com/~a!b@c%23d$e%25f^00&11*22(33)44_55+";
Canonicalize("http://3279880203/blah") = "http://195.127.0.11/blah";
Canonicalize("http://www.google.com/blah/..") = "http://www.google.com/";
Canonicalize("www.google.com/") = "http://www.google.com/";
Canonicalize("www.google.com") = "http://www.google.com/";
Canonicalize("http://www.evil.com/blah#frag") = "http://www.evil.com/blah";
Canonicalize("http://www.GOOgle.com/") = "http://www.google.com/";
Canonicalize("http://www.google.com.../") = "http://www.google.com/";
Canonicalize("http://www.google.com/foo\tbar\rbaz\n2") ="http://www.google.com/foobarbaz2";
Canonicalize("http://www.google.com/q?") = "http://www.google.com/q?";
Canonicalize("http://www.google.com/q?r?") = "http://www.google.com/q?r?";
Canonicalize("http://www.google.com/q?r?s") = "http://www.google.com/q?r?s";
Canonicalize("http://evil.com/foo#bar#baz") = "http://evil.com/foo";
Canonicalize("http://evil.com/foo;") = "http://evil.com/foo;";
Canonicalize("http://evil.com/foo?bar;") = "http://evil.com/foo?bar;";
Canonicalize("http://\x01\x80.com/") = "http://%01%80.com/";
Canonicalize("http://notrailingslash.com") = "http://notrailingslash.com/";
Canonicalize("http://www.gotaport.com:1234/") = "http://www.gotaport.com/";
Canonicalize("  http://www.google.com/  ") = "http://www.google.com/";
Canonicalize("http:// leadingspace.com/") = "http://%20leadingspace.com/";
Canonicalize("http://%20leadingspace.com/") = "http://%20leadingspace.com/";
Canonicalize("%20leadingspace.com/") = "http://%20leadingspace.com/";
Canonicalize("https://www.securesite.com/") = "https://www.securesite.com/";
Canonicalize("http://host.com/ab%23cd") = "http://host.com/ab%23cd";
Canonicalize("http://host.com//twoslashes?more//slashes") = "http://host.com/twoslashes?more//slashes";

Sufiks/prefiks

Po przekształceniu adresu kanonicznego adresu URL następnym krokiem jest utworzenie wyrażeń z sufiksem/prefiksem. Każde wyrażenie sufiksu/prefiksu składa się z sufiksu hosta (lub pełnego hosta) i prefiksu ścieżki (lub pełnej ścieżki), jak pokazano w tych przykładach.

Wyrażenie sufiksu/prefiksuOdpowiednik wyrażenia regularnego
a.b/mypath/
http\:\/\/.*\.a\.b\/mypath\/.*
c.d/full/path.html?myparam=a
http\:\/\/.*.c\.d\/full\/path\.html?myparam=a

Klient utworzy maksymalnie 30 różnych możliwych kombinacji sufiksu hosta i prefiksu ścieżki. Te kombinacje korzystają tylko z komponentów hosta i ścieżki adresu URL. Schemat, nazwa użytkownika, hasło i port są odrzucane. Jeśli adres URL zawiera parametry zapytania, co najmniej 1 kombinacja będzie zawierać pełną ścieżkę i parametry zapytania.

W przypadku hosta klient próbuje maksymalnie 5 różnych ciągów znaków. Są to:

  • Dokładna nazwa hosta w adresie URL.
  • Maksymalnie 4 nazwy hosta utworzone przez dodanie 5 ostatnich komponentów i stopniowe usuwanie wiodącego komponentu. Domenę najwyższego poziomu można pominąć. Te dodatkowe nazwy hostów nie powinny być sprawdzane, jeśli host jest adresem IP.

W przypadku ścieżki klient próbuje maksymalnie 6 różnych ciągów znaków. Są to:

  • Dokładna ścieżka adresu URL z parametrami zapytania.
  • Dokładna ścieżka adresu URL bez parametrów zapytania.
  • 4 ścieżki utworzone przez rozpoczynanie w miejscu głównym (/) i stopniowo dołączanie komponentów ścieżki, w tym z końcowym ukośnikiem.

Poniższe przykłady ilustrują zachowanie kontroli:

W przypadku adresu URL http://a.b.c/1/2.html?param=1 klient spróbuje wypróbować te możliwe ciągi:

a.b.c/1/2.html?param=1
a.b.c/1/2.html
a.b.c/
a.b.c/1/
b.c/1/2.html?param=1
b.c/1/2.html
b.c/
b.c/1/

W przypadku adresu URL http://a.b.c.d.e.f.g/1.html klient spróbuje wypróbować te możliwe ciągi:

a.b.c.d.e.f.g/1.html
a.b.c.d.e.f.g/
(Note: skip b.c.d.e.f.g, since we'll take only the last five hostname components, and the full hostname)
c.d.e.f.g/1.html
c.d.e.f.g/
d.e.f.g/1.html
d.e.f.g/
e.f.g/1.html
e.f.g/
f.g/1.html
f.g/

W przypadku adresu URL http://1.2.3.4/1/ klient spróbuje wypróbować te możliwe ciągi:

1.2.3.4/1/
1.2.3.4/

Obliczenia haszowania

Po utworzeniu zestawu wyrażeń z sufiksem/prefiksem następnym krokiem jest obliczenie skrótu SHA256 pełnej długości dla każdego wyrażenia. Poniżej znajduje się test jednostkowy (w pseudo-C), którego możesz użyć do weryfikacji obliczeń związanych z szyfrowaniem.

Przykłady z kodu FIPS-180-2:

Unit Test (in pseudo-C)

// Example B1 from FIPS-180-2
string input1 = "abc";
string output1 = TruncatedSha256Prefix(input1, 32);
int expected1[] = { 0xba, 0x78, 0x16, 0xbf };
assert(output1.size() == 4);  // 4 bytes == 32 bits
for (int i = 0; i < output1.size(); i++) assert(output1[i] == expected1[i]);

// Example B2 from FIPS-180-2
string input2 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
string output2 = TruncatedSha256Prefix(input2, 48);
int expected2[] = { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06 };
assert(output2.size() == 6);
for (int i = 0; i < output2.size(); i++) assert(output2[i] == expected2[i]);

// Example B3 from FIPS-180-2
string input3(1000000, 'a');  // 'a' repeated a million times
string output3 = TruncatedSha256Prefix(input3, 96);
int expected3[] = { 0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92,
                    0x81, 0xa1, 0xc7, 0xe2 };
assert(output3.size() == 12);
for (int i = 0; i < output3.size(); i++) assert(output3[i] == expected3[i]);

Obliczanie prefiksu skrótu

Na koniec klient musi obliczyć prefiks skrótu dla każdego skrótu SHA256 pełnej długości. W przypadku Bezpiecznego przeglądania prefiks skrótu składa się z najważniejszych 4–32 bajtów skrótu SHA256.

Przykłady z kodu FIPS-180-2:

  • Przykład B1 z FIPS-180-2
    • Wpisz „abc”.
    • Skrót SHA256 to ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad.
    • 32-bitowy prefiks skrótu to ba7816bf.
  • Przykład B2 z FIPS-180-2
    • Dane wejściowe to „abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq”.
    • Skrót SHA256 to 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1.
    • 48-bitowy prefiks skrótu to 248d6a61 d206.