Overview

API de Oblivious HTTP Gateway de Navegación segura

Nota: Actualmente, esta documentación aún está en desarrollo. Se prevén mejoras en el futuro cercano.

La API de Oblivious HTTP Gateway de Navegación segura es una API que preserva la privacidad y está compilada sobre el protocolo IETF RFC llamado Oblivious HTTP, RFC 9458.

Descripción general

La API de Oblivious HTTP Gateway de Navegación segura es un servicio de Google que permite que las aplicaciones cliente verifiquen las URLs con las listas de Google de recursos web no seguros, las cuales se actualizan constantemente, con protecciones de privacidad adicionales implementadas.

Esto se logra mediante un protocolo ligero llamado Oblivious HTTP, o bien OHTTP. Este es un protocolo sin estado que pueden usar los clientes de Navegación segura para acceder a las APIs de Navegación segura de Google V5 para obtener protecciones sólidas y una mayor cobertura sin comprometer la privacidad de los usuarios.

NOTA: No se puede acceder a las APIs de Google Safe Browsing V4 a través de este servicio.

Protocolo HTTP Oblivious de Navegación segura

Protocolo RFC

Oblivious HTTP es un protocolo ligero definido en RFC 9458, que se usa para encriptar y enviar mensajes HTTP de un cliente a un servidor de destino. Se usa un servicio de retransmisión confiable que mitiga el uso de metadatos del servidor de destino, como la dirección IP y la información de conexión para la identificación del cliente, lo que brinda privacidad y seguridad además del protocolo HTTP/S simple. El protocolo usa HTTP binario, definido en RFC 9292, para codificar/decodificar las solicitudes y respuestas HTTP.

En un nivel superior, Relay se interconecta entre el recurso cliente y Gateway que representa el tráfico del cliente eliminando todos los identificadores de cliente, incluidos los atributos sensibles de privacidad, como las direcciones IP, lo que anonimiza de manera efectiva las solicitudes HTTP entrantes al servicio Gateway. El beneficio adicional de OHTTP es que todas las solicitudes están encriptadas de extremo a extremo, lo que significa que las consultas de los clientes de Navegación segura (es decir, los hashes truncados de las expresiones de URL) no son visibles para Relay. Consulta blogpost para ver un ejemplo de implementación en Chrome.

Es la arquitectura general del servicio.
Fig: Flujo de OHTTP.

Los clientes pueden elegir cualquier proveedor de Relay (p. ej., Fastly) para integrarse en el servicio. Relay debe usar la autenticación Oauth 2.0 con el siguiente alcance de autorización para acceder al servicio.


// OAuth Authorization scope: https://www.googleapis.com/auth/3p-relay-safe-browsing
Extremos de la API
Clave pública OHTTP

Este extremo proporcionará la configuración de clave pública OHTTP según se especifica en RFC 9458, que el cliente usará para encriptar las solicitudes OHTTP.


GET https://safebrowsingohttpgateway.googleapis.com/v1/ohttp/hpkekeyconfig?key=<API key>

Esta clave de API no es estrictamente necesaria; el servidor no modifica la clave pública OHTTP según la clave de API proporcionada. Se permite a los clientes sondear este hecho utilizando diferentes claves de API válidas para acceder a este extremo o sin utilizar ninguna clave de API por completo y comprobando que la respuesta realmente contenga la misma clave pública OHTTP. Sin embargo, para facilitar la depuración, se recomienda usar una clave de API. Esto permite a los clientes ver estadísticas como la cantidad de solicitudes en la consola de Google Cloud. Si el cliente quiere proporcionar una clave de API, consulta esta documentación sobre cómo configurar claves de API.

Como se indica en la sección de recomendaciones de privacidad, para cumplir con los objetivos de coherencia de las claves, se recomienda que los proveedores cliente configuren una infraestructura de distribución de claves centralizada para recuperar la clave de este extremo y, luego, distribuirla a sus aplicaciones cliente.

Según la guía de administración de claves, las claves se rotan con regularidad en el servidor. Los clientes deben actualizar la clave, es decir, recuperar y actualizar la copia local de la clave de vez en cuando para evitar fallas de desencriptación.

Los clientes deben actualizar (recuperar y actualizar) la clave pública una vez al día. Si se usa un mecanismo de distribución centralizada, este mecanismo debería asegurarse de recuperar y distribuir las claves una vez al día.

Solicitud encapsulada OHTTP

Este extremo entregará la solicitud OHTTP que se incluye en el cuerpo HTTP de la solicitud POST mediante la desencriptación de la solicitud y, luego, encriptará la respuesta OHTTP para que se reenvíe a Relay en la respuesta HTTP. El cliente debe incluir un encabezado de solicitud Content-Type como message/ohttp-req en la solicitud HTTP POST.


POST https://safebrowsingohttpgateway.googleapis.com/v1/ohttp:handleOhttpEncapsulatedRequest?key=<API key>

NOTA: Según las indicaciones sobre RFC, codifica la solicitud interna (consulta la documentación de V5 sobre cómo compilar una solicitud de Navegación segura) con el protocolo HTTP binario, RFC 9292.

Bibliotecas cliente

Google Quiche tiene implementaciones del cliente para los protocolos OHTTP y BHTTP. Se recomienda que los clientes usen estas bibliotecas. Consulta a continuación el seudocódigo sobre cómo compilar solicitudes OHTTP para acceder a la API.

Ejemplo de implementación del cliente

Los clientes recuperan la clave pública HTTP Oblivious desde el extremo de clave pública. Luego, inicializa la configuración de la clave OHTTP del quiche y, luego, el cliente OHTTP del quiche.


auto ohttp_key_cfgs = quiche::ObliviousHttpKeyConfigs::ParseConcatenatedKeys(std::string public_key); auto key_config = ohttp_key_cfgs->PreferredConfig(); auto public_key = ohttp_key_cfgs->GetPublicKeyForId(key_config.GetKeyId()) auto ohttp_client = quiche::ObliviousHttpClient::Create(public_key, key_config);

El cliente usará la codificación HTTP binaria para crear la solicitud BHTTP como primer paso antes de la encriptación.


quiche::BinaryHttpRequest::ControlData bhttp_ctrl_data{ .method = "POST", .scheme = "https", .authority = "safebrowsing.googleapis.com", .path = "/v5/hashes:search?key=<API key>&hashPrefixes=<HASH prefix 1>&hashPrefixes=<HASH prefix 2>", }; quiche::BinaryHttpRequest bhttp_request(bhttp_ctrl_data);

Luego, el cliente encriptará la solicitud HTTP binaria creada en el paso anterior.


auto bhttp_serialized = bhttp_request.Serialize(); auto ohttp_request = ohttp_client.CreateObliviousHttpRequest(*bhttp_serialized); // Client must include this in POST body, and add `Content-Type` header as "message/ohttp-req". auto payload_include_in_post_body = ohttp_request.EncapsulateAndSerialize();

Una vez que se recibe la respuesta de Relay, el cliente la desencriptará. La respuesta incluirá un encabezado de respuesta Content-Type como ohttp-res.


auto ctx = std::move(ohttp_request).ReleaseContext(); auto ohttp_response = ohttp_client.DecryptObliviousHttpResponse("data included in body of http_response", ctx);

Después de desencriptar la respuesta OHTTP correctamente, decodifica el resultado con HTTP binario de esta manera.


auto bhttp_response = BinaryHttpResponse::Create(ohttp_response.GetPlaintextData()); if (bhttp_response.status_code() == 200) { auto http_response = bhttp_response.body(); auto response_headers = bhttp_response.GetHeaderFields(); }