Безопасный просмотр 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.
Клиенты могут выбрать любого поставщика реле (например, 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();
}