Adresy URL i haszowanie

Ten dokument dotyczy tej metody: Interfejs Update API (w wersji 4): fullHashes.find.

Omówienie

Listy Bezpiecznego przeglądania zawierają hasze SHA-256 o zmiennej długości (patrz Treści list). Aby sprawdzić adres URL na liście Bezpiecznego przeglądania (lokalnie lub na serwerze), klienci muszą najpierw obliczyć prefiks hasha tego adresu URL.

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

  1. Zastosuj kanoniczny adres URL (patrz Konwertowanie kanoniczne).
  2. Utwórz wyrażenia sufiksu/prefiksu dla adresu URL (patrz Wyrażenia sufiksu/prefiksu).
  3. Oblicz pełnowymiarowy skrót dla każdego wyrażenia sufiksu/prefiksu (patrz Obliczanie skrótów).
  4. Oblicz prefiks skrótu dla każdego skrótu o pełnej długości (zobacz Obliczanie prefiksów skrótu).

Te kroki są odzwierciedleniem procesu używanego przez serwer Bezpiecznego przeglądania do Przeglądanie list.

Konwertowanie kanoniczne

Na początek zakładamy, że klient przeanalizował adres URL i przyznał jego poprawność zgodnie ze standardem RFC 2396. Jeśli adres URL zawiera międzynarodową nazwę domeny (IDN), klient powinien przekonwertować adres URL do postaci ASCII Punycode. Adres URL musi zawierać element ścieżki, czyli ukośnik na końcu („http://google.com/”).

Najpierw usuń znaki tabulacji (0x09), CR (0x0d) i LF (0x0a) z adres URL. 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ócenie adresu „http://google.com/#frag” do „http://google.com/”.

Po trzecie, wielokrotnie zmieniaj znak znaczenia procenta, aż w adresie URL nie będzie już znaków zmiany znaczenia.

Aby zmienić nazwę hosta na postać kanoniczną:

Wyodrębnij nazwę hosta z adresu URL, a potem:

  1. Usuń wszystkie kropki na początku i na końcu.
  2. Zastąp kolejne kropki jedną kropką.
  3. Jeśli nazwę hosta można przeanalizować jako adres IP, znormalizuj ją do 4 wartości dziesiętnych oddzielonych kropkami. Klient powinien zadbać o wszelkie legalne kodowanie adresów IP, w tym ósemkowy, szesnastkowy i mniej niż cztery.
  4. Cały ciąg należy pisać małymi literami.

Aby określić ścieżkę kanoniczną:

  1. Rozwiąż sekwencje „/../” i „/./” na ścieżce o zastępując „/./” „/” i usunięcie „/../” wraz z poprzednią ścieżką .
  2. Zastąp ciągi kolejnych ukośników jednym ukośnikiem.

Nie stosuj kanonizacji ścieżek do parametrów zapytania.

W adresie URL użyj znaku procenta zmiany znaczenia <= ASCII 32, >= 127, „#” lub „%”. W adresach e-mail powinny być używane znaki ucieczki wielkich liter szesnastkowych.

Poniżej znajdziesz testy, które pomogą Ci sprawdzić poprawność implementacji konwertowania kanonicznego.

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";

Wyrażenia z sufiksem lub preiksem

Następnym krokiem po przekształceniu adresu URL jest utworzenie wyrażenia sufiksu/prefiksu. Każdy sufiks/wyrażenie prefiksu składa się z sufiksu hosta (lub pełnego hosta) i prefiksu ścieżki (lub pełnej ścieżki) jak widać na tych przykładach.

Wyrażenie sufiksu/prefiksuRównoważne wyrażenie regularne
a.b/mypath/
http\:\/\/.*\.a\.b\/mypath\/.*
c.d/full/path.html?myparam=a
http\:\/\/.*.c\.d\/full\/path\.html?myparam=a

Klient utworzy do 30 różnych możliwych kombinacji sufiksów hosta i prefiksów ścieżki. W tych kombinacjach używane są tylko komponenty hosta i ścieżki adresu URL. schemat, nazwę użytkownika, hasło i port zostaną odrzucone. 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 wypróbować maksymalnie 5 różnych ciągów. Są to:

  • Dokładna nazwa hosta w adresie URL.
  • Maksymalnie 4 nazwy hostów utworzone na podstawie ostatnich 5 komponentów z kolejnym usuwaniem pierwszego komponentu. Domena najwyższego poziomu może zostać pominięta. Te dodatkowe nazwy hostów nie powinny być sprawdzane, jeśli host to adres IP.

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

  • Dokładna ścieżka adresu URL, w tym parametry zapytania.
  • Dokładna ścieżka adresu URL, bez parametrów zapytania.
  • 4 ścieżki powstałe, zaczynając od pierwiastka (/) i dołączając kolejno ścieżkę włącznie z ukośnikiem na końcu.

Poniższe przykłady ilustrują proces sprawdzania:

W przypadku adresu URL http://a.b.c/1/2.html?param=1 klient spróbuje użyć tych możliwych ciągów:

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 użyć tych ciągów znaków:

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 wykonać te czynności strings:

1.2.3.4/1/
1.2.3.4/

Obliczenia haszowania

Po utworzeniu zestawu wyrażeń przyrostowych i prefiksów następnym krokiem jest obliczenie hasz SHA256 pełnej długości każdego wyrażenia. Poniżej znajdziesz test jednostkowy (w pseudojęzyku C), który możesz wykorzystać do sprawdzenia obliczeń haszowania.

Przykłady z 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]);

Obliczenia prefiksów skrótu

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

Przykłady z: FIPS-180-2:

  • Przykład B1 z normy FIPS-180-2
    • Dane wejściowe to „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
    • Obecne dane wejściowe: „abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq”.
    • Skrót SHA256 to 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1.
    • 48-bitowy prefiks hasza to 248d6a61 d206.