URL e hashing

Questo documento si applica al seguente metodo: API Update (v4): fullHashes.find.

Panoramica

Gli elenchi di Navigazione sicura sono costituiti da hash SHA256 di lunghezza variabile. (consulta la sezione Contenuti dell'elenco). Per verificare un URL in base a un elenco di Navigazione sicura (localmente o sul server), i client devono prima calcolare il prefisso dell'hash dell'URL.

Per calcolare il prefisso dell'hash di un URL:

  1. Canonizza l'URL (vedi Canonicalizzazione).
  2. Crea le espressioni suffisso/prefisso per l'URL (consulta la sezione Espressioni di suffisso/prefisso).
  3. Calcola l'hash completo per ogni espressione di suffisso/prefisso (vedi Calcoli hash).
  4. Calcola il prefisso hash per ogni hash completo (consulta Calcoli del prefisso hash).

Tieni presente che questi passaggi rispecchiano la procedura utilizzata dal server di Navigazione sicura per gestire Sfogliare elenchi.

Canonicalizzazione

Per iniziare, supponiamo che il client abbia analizzato l'URL e lo abbia reso valido in base allo standard RFC 2396. Se l'URL utilizza un nome di dominio internazionalizzato (IDN), il client deve convertire l'URL nel Rappresentazione Punycode ASCII. L'URL deve includere un componente del percorso, ovvero deve avere una barra finale ("http://google.com/").

Innanzitutto, rimuovi i caratteri Tab (0x09), CR (0x0d) e LF (0x0a) da l'URL. Non rimuovere le sequenze di escape per questi caratteri (ad es. "%0a").

In secondo luogo, se l'URL termina con un frammento, rimuovilo. Ad esempio, abbrevia "http://google.com/#frag" a "http://google.com/".

In terzo luogo, elimina ripetutamente caratteri di escape percentuali dell'URL finché non sono presenti più caratteri di escape percentuali.

Per eseguire la canonizzazione del nome host:

Estrai il nome host dall'URL e quindi:

  1. Rimuovi tutti i punti iniziali e finali.
  2. Sostituisci i punti consecutivi con un unico punto.
  3. Se il nome host può essere analizzato come indirizzo IP, normalizzalo in 4 valori decimali separati da punti. Il client deve gestire la codifica legale degli indirizzi IP inclusi ottale, esadecimale e meno di quattro componenti.
  4. Scrivi tutta la stringa in minuscolo.

Per canonicalizzare il percorso:

  1. Risolvi le sequenze "/../" e "/./" nel percorso, sostituzione "/./" con "/" e la rimozione di "/../" insieme al percorso precedente di strumento di authoring.
  2. Sostituisci le serie di barre consecutive con un singolo carattere barra.

Non applicare queste canonizzazioni dei percorsi ai parametri di query.

Nell'URL, utilizza il tasto percentuale di escape per tutti i caratteri. che sono <= ASCII 32, >= 127, "#" o "%". Le sequenze di escape devono utilizzare esadecimali maiuscoli.

Di seguito sono riportati i test che consentono di convalidare un'implementazione della canonizzazione.

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

Espressioni con suffisso/prefisso

Dopo aver canonicalizzato l'URL, il passaggio successivo consiste nel creare le espressioni suffisso/prefisso. Ciascuna L'espressione di suffisso/prefisso è composta da un suffisso host (o host completo) e da un prefisso di percorso (o percorso completo) come mostrato in questi esempi.

Espressione suffisso/prefissoEspressione regolare equivalente
a.b/mypath/
http\:\/\/.*\.a\.b\/mypath\/.*
c.d/full/path.html?myparam=a
http\:\/\/.*.c\.d\/full\/path\.html?myparam=a

Il client formerà fino a 30 diverse combinazioni possibili di suffisso host e prefisso del percorso. Queste combinazioni utilizzano solo i componenti host e il percorso dell'URL. Lo schema, il nome utente la password e la porta vengono ignorate. Se l'URL include parametri di query, allora almeno uno includerà il percorso completo e i parametri di query.

Per l'host, il client proverà al massimo cinque stringhe diverse. Sono:

  • Il nome host esatto nell'URL.
  • Vengono creati fino a quattro nomi host iniziando dagli ultimi cinque componenti e rimuovendo il componente principale in successione. Il dominio di primo livello può essere ignorato. Questi nomi host aggiuntivi non devono essere selezionati se l'host è un indirizzo IP.

Per il percorso, il client proverà al massimo sei stringhe diverse. Sono:

  • Il percorso esatto dell'URL, inclusi i parametri di query.
  • Il percorso esatto dell'URL, senza parametri di query.
  • I quattro percorsi formati iniziando dalla radice (/) e aggiungendo successivamente il percorso tra cui una barra finale.

I seguenti esempi illustrano il comportamento del controllo:

Per l'URL http://a.b.c/1/2.html?param=1, il client proverà questi possibili:

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/

Per l'URL http://a.b.c.d.e.f.g/1.html, il client proverà queste possibili stringhe:

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/

Per l'URL http://1.2.3.4/1/, il client proverà queste opzioni strings:

1.2.3.4/1/
1.2.3.4/

Calcoli di hash

Una volta creato l'insieme di espressioni suffisso/prefisso, il passaggio successivo è calcolare il valore hash SHA256 a lunghezza intera per ogni espressione. Di seguito è riportato un test unitario (in pseudo-C) che puoi utilizzare per convalidare i calcoli delle hash.

Esempi da 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]);

Calcoli dei prefissi hash

Infine, il client deve calcolare il prefisso dell'hash per ogni hash SHA256 di lunghezza completa. Per la sicurezza Durante la navigazione, un prefisso hash è costituito dai 4-32 byte più significativi di un hash SHA256.

Esempi tratti da FIPS-180-2:

  • Esempio B1 da FIPS-180-2
    • L'input è "abc".
    • Il digest SHA256 è ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad.
    • Il prefisso dell'hash a 32 bit è ba7816bf.
  • Esempio B2 da FIPS-180-2
    • L'input è "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".
    • Il digest SHA256 è 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1.
    • Il prefisso dell'hash a 48 bit è 248d6a61 d206.