URL y codificación hash

Este documento se aplica al siguiente método: API de Update (v4): fullHashes.find.

Descripción general

Las listas de Navegación segura constan de hash SHA256 de longitud variable. (consulta el contenido de la lista). Para comparar una URL con una lista de Navegación segura (ya sea de forma local o en el servidor), los clientes primero deben calcular el prefijo hash de esa URL.

Para calcular el prefijo de hash de una URL, sigue estos pasos:

  1. Canonicaliza la URL (consulta Canonicalización).
  2. Crea las expresiones de sufijo o prefijo para la URL (consulta Expresiones de sufijo o prefijo).
  3. Calcula el hash de longitud total para cada expresión de sufijo/prefijo (consulta Cálculos de hash).
  4. Calcula el prefijo de hash para cada hash de longitud completa (consulta Cálculos de prefijos hash).

Ten en cuenta que estos pasos reflejan el proceso que usa el servidor de Navegación segura para mantener Explorar listas

Canonicalización

Para comenzar, suponemos que el cliente analizó la URL y la hizo válida de acuerdo con RFC 2396. Si la URL utiliza un nombre de dominio internacionalizado (IDN), el cliente debe convertir la URL al Representación ASCII Punycode. La URL debe incluir un componente de ruta de acceso. es decir, debe tener barra final ("http://google.com/").

Primero, quita los caracteres de tabulación (0x09), CR (0x0d) y LF (0x0a) de la URL. No quites las secuencias de escape para estos caracteres (p.ej., "%0a").

En segundo lugar, si la URL termina en un fragmento, quítalo. Por ejemplo, acortar "http://google.com/#frag" a "http://google.com/".

Tercero, elimina el escape porcentual de manera repetida de la URL hasta que no tenga más escapes porcentuales.

Para canonizar el nombre de host, haz lo siguiente:

Extrae el nombre de host de la URL y luego haz lo siguiente:

  1. Quita todos los puntos iniciales y finales.
  2. Reemplaza los puntos consecutivos por un solo punto.
  3. Si el nombre de host se puede analizar como una dirección IP, normalízalo hasta 4 valores decimales separados por puntos. El cliente debe manejar cualquier codificación de dirección IP legal, incluidos octal, hexadecimal y menos de cuatro componentes.
  4. Pon en minúscula toda la string.

Para canonicalizar la ruta de acceso, sigue estos pasos:

  1. Para resolver las secuencias "/../" y "/./" en la ruta de acceso, reemplaza "/./" por "/" y quita "/../" junto con el componente de ruta de acceso anterior.
  2. Reemplaza las ejecuciones de barras consecutivas por un solo carácter de barra.

No apliques estas canonicalizaciones de ruta a los parámetros de búsqueda.

En la URL, el porcentaje de escape de todos los caracteres que son <= ASCII 32, >= 127, "#" o "%". Los caracteres de escape deben usar caracteres hexadecimales en mayúsculas.

A continuación, se incluyen pruebas para ayudar a validar una implementación de canonización.

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

Suffix/prefix expressions

Una vez que se canoniza la URL, el siguiente paso es crear las expresiones de sufijo o prefijo. Cada expresión de sufijo o prefijo consta de un sufijo de host (o host completo) y un prefijo de ruta de acceso (o ruta de acceso completa) como se muestra en estos ejemplos.

Expresión de sufijo o prefijoExpresión regular equivalente
a.b/mypath/
http\:\/\/.*\.a\.b\/mypath\/.*
c.d/full/path.html?myparam=a
http\:\/\/.*.c\.d\/full\/path\.html?myparam=a

El cliente formará hasta 30 combinaciones diferentes de sufijo de host y prefijo de ruta de acceso. Estas combinaciones solo usan los componentes de host y ruta de acceso de la URL. Se descartan el esquema, el nombre de usuario, la contraseña y el puerto. Si la URL incluye parámetros de consulta, al menos una combinación incluirá la ruta completa y los parámetros de consulta.

Para el host, el cliente intentará como máximo con cinco strings diferentes. Son:

  • El nombre de host exacto en la URL.
  • Hasta cuatro nombres de host formados a partir de los últimos cinco componentes y, de forma sucesiva, quitando el componente principal. Se puede omitir el dominio de nivel superior. Estos no se deben revisar los nombres de host adicionales si el host es una dirección IP.

Para la ruta, el cliente intentará como máximo con seis strings diferentes. Ellas son:

  • La ruta exacta de la URL, incluidos los parámetros de búsqueda.
  • La ruta exacta de la URL, sin parámetros de búsqueda.
  • Las cuatro rutas que se forman a partir de la raíz (/) y la adición de rutas de forma sucesiva componentes, incluida una barra diagonal final.

En los siguientes ejemplos, se ilustra el comportamiento de la verificación:

Para la URL http://a.b.c/1/2.html?param=1, el cliente probará estas cadenas posibles:

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/

Para la URL http://a.b.c.d.e.f.g/1.html, el cliente probará estas posibles strings:

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/

Para la URL http://1.2.3.4/1/, el cliente probará estas posibles cadenas:

1.2.3.4/1/
1.2.3.4/

Cálculos de hash

Una vez creado el conjunto de expresiones de sufijo/prefijo, el siguiente paso es calcular la hash SHA256 completo para cada expresión. Es una prueba de unidades (en seudo-C) que puedes usar para validar tu de hash se proporcionan a continuación.

Ejemplos de 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]);

Cálculos de prefijo hash

Por último, el cliente debe calcular el prefijo hash para cada hash SHA256 de longitud total. Para la Navegación segura, un prefijo hash consta de los 4 a 32 bytes más significativos de un hash SHA256.

Ejemplos de FIPS-180-2:

  • Ejemplo B1 de FIPS-180-2
    • La entrada es “abc”.
    • El resumen de SHA256 es ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad
    • El prefijo hash de 32 bits es ba7816bf.
  • Ejemplo B2 de FIPS-180-2
    • La entrada es “abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq”.
    • El resumen SHA256 es 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1.
    • El prefijo hash de 48 bits es 248d6a61 d206.