Overview

Безопасный просмотр API Oblivious HTTP Gateway

Примечание. Эта документация в настоящее время все еще находится в стадии разработки. Ожидайте улучшения в ближайшем будущем.

Безопасный просмотр Oblivious HTTP Gateway API — это API-интерфейс, обеспечивающий конфиденциальность, созданный на основе протокола IETF RFC под названием Oblivious HTTP , RFC 9458 .

Обзор

Безопасный просмотр Oblivious HTTP Gateway API — это служба Google, которая позволяет клиентским приложениям проверять URL-адреса на соответствие постоянно обновляемым спискам небезопасных веб-ресурсов Google с дополнительной защитой конфиденциальности.

Это достигается с помощью облегченного протокола Oblivious HTTP или сокращенно OHTTP . Это протокол без сохранения состояния, который может использоваться клиентами безопасного просмотра для доступа к API Google Safe Browsing V5 , чтобы обеспечить надежную защиту и расширенный охват без ущерба для конфиденциальности пользователей.

ПРИМЕЧАНИЕ. Доступ к API Google Safe Browsing V4 через эту службу недоступен.

Безопасный просмотр. Не обращая внимания на протокол HTTP.

Протокол RFC

Oblivious HTTP — это облегченный протокол, определенный в RFC 9458 , используемый для шифрования и отправки HTTP-сообщений от клиента на целевой сервер. При этом используется доверенная служба ретрансляции таким образом, чтобы минимизировать использование целевым сервером метаданных, таких как IP-адрес и информация о соединении, для идентификации клиента, обеспечивая конфиденциальность и безопасность поверх простого протокола HTTP/S. Протокол использует двоичный HTTP, определенный в RFC 9292, для кодирования/декодирования HTTP-запросов/ответов.

На высоком уровне между ресурсом клиента и шлюза стоит ретранслятор, который передает клиентский трафик путем удаления всех идентификаторов клиента, включая чувствительные к конфиденциальности атрибуты, такие как IP-адреса, эффективно анонимизируя входящие HTTP-запросы к службе шлюза. Дополнительным преимуществом OHTTP является то, что все запросы имеют сквозное шифрование, что означает, что запросы безопасного просмотра клиентов (т. е. усеченные хэши выражений URL-адресов) не видны ретранслятору. Обратитесь к сообщению в блоге , где приведен пример реализации в Chrome.

Общая архитектура сервиса.
Рис .: поток HTTP.

Клиенты могут выбрать любого поставщика реле (например, Fastly ) для интеграции с сервисом. Для доступа к услуге реле должно использовать аутентификацию Oauth 2.0 со следующей областью авторизации .


// OAuth Authorization scope: https://www.googleapis.com/auth/3p-relay-safe-browsing
Конечные точки API
Открытый ключ HTTP

Эта конечная точка предоставит конфигурацию открытого ключа OHTTP , как указано в RFC 9458 , который будет использоваться клиентом для шифрования запроса OHTTP.


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

Указанный выше ключ API не является строго необходимым; сервер не меняет открытый ключ OHTTP в зависимости от предоставленного ключа API. Клиентам разрешено проверять этот факт, используя разные действительные ключи API для доступа к этой конечной точке или вообще не используя ключи API, а также проверяя, действительно ли ответ содержит один и тот же открытый ключ OHTTP. Однако для упрощения отладки рекомендуется использовать ключ API; это позволяет клиентам просматривать статистику, например количество запросов, в Google Cloud Console. Если клиент намерен предоставить ключ API, обратитесь к этой документации , чтобы узнать, как настроить ключи API.

Как указано в разделе рекомендаций по конфиденциальности , для достижения целей согласованности ключей поставщикам клиентов рекомендуется создать централизованную инфраструктуру распределения ключей , чтобы получать ключ из этой конечной точки и впоследствии распространять его среди своих клиентских приложений.

В соответствии с руководством по управлению ключами ключи на сервере регулярно меняются. Клиентам следует обновлять ключ, т. е. время от времени получать и обновлять локальную копию ключа, чтобы избежать ошибок расшифровки.

Клиенты должны обновлять (извлекать и обновлять) открытый ключ один раз в день. Если используется механизм централизованного распространения, этот механизм должен обеспечивать получение и распространение ключей один раз в день.

Инкапсулированный запрос HTTP

Эта конечная точка будет обслуживать запрос OHTTP, включенный в тело HTTP запроса POST, выполняя расшифровку запроса и впоследствии шифруя ответ OHTTP для пересылки обратно в ретранслятор в ответе HTTP. Клиент должен включить заголовок запроса Content-Type как message/ohttp-req в запрос HTTP POST.


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

ПРИМЕЧАНИЕ. В соответствии с рекомендациями RFC закодируйте внутренний запрос (о том, как создать запрос безопасного просмотра, см. документацию V5 ), используя двоичный протокол HTTP , RFC 9292 .

Клиентские библиотеки

Google Quiche имеет реализации на стороне клиента как для протоколов OHTTP , так и для BHTTP . Клиентам рекомендуется использовать эти библиотеки. Ниже приведен псевдокод о том, как создавать запросы OHTTP для доступа к API.

Пример реализации на стороне клиента

Клиенты получают открытый ключ HTTP Oblivious из конечной точки открытого ключа . Затем инициализируйте конфигурацию ключа OHTTP для пирога, как показано ниже, и инициализируйте клиент OHTTP для пирога.


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

Клиент будет использовать двоичное кодирование HTTP для создания запроса BHTTP в качестве первого шага перед шифрованием.


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

Клиент впоследствии зашифрует двоичный HTTP-запрос, созданный на предыдущем шаге.


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();

Как только ответ будет получен от Relay, клиент расшифрует ответ. Ответ будет включать заголовок ответа Content-Type как ohttp-res .


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

После успешной расшифровки ответа OHTTP декодируйте выходные данные, используя двоичный HTTP, вот так.


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(); }