Overview

Bezpieczne przeglądanie: Oblivious HTTP Gateway API

Uwaga: ta dokumentacja jest obecnie w trakcie opracowywania. W najbliższej przyszłości wprowadzimy te ulepszenia.

Bezpieczne przeglądanie Oblivious HTTP Gateway API to interfejs API chroniący prywatność, oparty na protokole IETF RFC o nazwie Oblivious HTTP, RFC 9458.

Przegląd

Bezpieczne przeglądanie: Oblivious HTTP Gateway API to usługa Google, która umożliwia aplikacjom klienckim sprawdzanie adresów URL pod kątem stale aktualizowanych przez Google list niebezpiecznych zasobów internetowych. Stosowane są także dodatkowe zabezpieczenia prywatności.

Do osiągnięcia tego celu służy prostszy protokół o nazwie Oblivious HTTP (Oblivious HTTP) (w skrócie OHTTP). Jest to bezstanowy protokół, którego klienci mogą używać do uzyskiwania dostępu do interfejsów API Bezpiecznego przeglądania Google w wersji 5. Pozwalają one uzyskać niezawodne zabezpieczenia i zwiększyć zasięg bez naruszania prywatności użytkowników.

UWAGA: za pomocą tej usługi nie można uzyskać dostępu do interfejsów API Bezpiecznego przeglądania Google (wersja 4).

Protokół HTTP Bezpieczne przeglądanie

Protokół RFC

Oblivious HTTP to prosty protokół zdefiniowany w RFC 9458. Służy do szyfrowania i wysyłania wiadomości HTTP z klienta na serwer docelowy. Ta usługa korzysta z zaufanej usługi przekaźnika w sposób, który ogranicza wykorzystywanie przez serwer docelowy metadanych takich jak adres IP i informacje o połączeniu do identyfikacji klienta, zapewniając prywatność i bezpieczeństwo w porównaniu ze zwykłym protokołem HTTP/S. Protokół ten korzysta z binarnego protokołu HTTP zdefiniowanego w RFC 9292 do kodowania/dekodowania żądań/odpowiedzi HTTP.

Ogólnie rzecz biorąc, przekaźnik stoi między zasobem klienta a bramą, który pośredniczy w ruchu klientów przez serwer proxy, usuwając wszystkie identyfikatory klientów, w tym atrybuty wrażliwe na potrzeby prywatności, takie jak adresy IP, skutecznie anonimizując przychodzące żądania HTTP do usługi bramy. Dodatkową zaletą protokołu OHTTP jest pełne szyfrowanie wszystkich żądań, co oznacza, że zapytania Bezpiecznego przeglądania klientów (tj. obcięte hasze wyrażeń URL) nie są widoczne dla przekaźnika. Przykład implementacji w Chrome znajdziesz w poście na blogu.

Ogólna architektura usługi.
Rys.: Przepływ protokołu OHTTP.

Klienci mogą wybrać dowolnego dostawcę usługi przekaźnika (np. Szybko), aby zintegrować ją z usługą. Aby usługa mogła mieć dostęp do usługi, usługa przekaźnika musi korzystać z uwierzytelniania Oauth 2.0 z następującym zakresem autoryzacji.


// OAuth Authorization scope: https://www.googleapis.com/auth/3p-relay-safe-browsing
Punkty końcowe interfejsu API
Klucz publiczny OHTTP

Ten punkt końcowy udostępni konfigurację klucza publicznego OHTTP zgodnie z opisem w RFC 9458, której klient będzie używać do szyfrowania żądania OHTTP.


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

Powyższy klucz interfejsu API nie jest bezwzględnie wymagany. Serwer nie zmienia klucza publicznego OHTTP na podstawie podanego klucza interfejsu API. Klienty mogą analizować ten fakt, używając różnych prawidłowych kluczy interfejsu API do uzyskiwania dostępu do tego punktu końcowego lub też nie używając żadnych kluczy interfejsu API i sprawdzając, czy odpowiedź faktycznie zawiera ten sam klucz publiczny OHTTP. Jednak ze względu na łatwość debugowania zalecamy użycie klucza interfejsu API, który umożliwia klientom wyświetlanie statystyk, takich jak liczba żądań, w konsoli Google Cloud. Jeśli klient zamierza dostarczyć klucz interfejsu API, zapoznaj się z tą dokumentacją, aby dowiedzieć się, jak skonfigurować klucze interfejsu API.

Jak wspomnieliśmy w sekcji Rekomendacje dotyczące prywatności, w celu osiągnięcia celów dotyczących spójności kluczy zalecamy, aby dostawcy klientów skonfigurowali infrastrukturę scentralizowanego dystrybucji kluczy, aby pobierać klucz z tego punktu końcowego, a następnie rozpowszechniać go do swoich aplikacji klienckich.

Zgodnie ze wskazówkami dotyczącymi zarządzania kluczami klucze są regularnie rotowane na serwerze. Klienci powinni odświeżać klucz, tj. regularnie pobierać i aktualizować jego lokalną kopię, aby uniknąć błędów odszyfrowywania.

Klienci powinni odświeżać (pobierać i aktualizować) klucz publiczny raz dziennie. Jeśli używany jest scentralizowany mechanizm dystrybucji, ten mechanizm powinien pobierać i rozpowszechniać klucze raz dziennie.

Żądanie zamknięte przez protokół OHTTP

Ten punkt końcowy będzie obsługiwać żądanie OHTTP zawarte w treści HTTP żądania POST, przeprowadzając odszyfrowanie żądania, a następnie szyfruje odpowiedź OHTTP, która ma zostać przekazana z powrotem do usługi Relay w odpowiedzi HTTP. Klient musi uwzględnić nagłówek żądania Content-Type jako message/ohttp-req w żądaniu HTTP POST.


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

UWAGA: zgodnie ze wskazówkami w RFC zakoduj żądanie wewnętrzne (zapoznaj się z dokumentacją V5 dotyczącą tworzenia żądania Bezpiecznego przeglądania), korzystając z protokołu Binary HTTP (RFC 9292).

Biblioteki klienta

Google Quiche ma implementacje po stronie klienta zarówno dla protokołów OHTTP, jak i BHTTP. Klientom zalecamy używanie tych bibliotek. Poniżej znajdziesz pseudokod, z którego dowiesz się, jak tworzyć żądania OHTTP w celu uzyskania dostępu do interfejsu API.

Przykładowa implementacja po stronie klienta

Klienty pobierają klucz publiczny HTTP Oblivious HTTP z punktu końcowego klucza publicznego. Następnie w ten sposób zainicjuj konfigurację klucza OHTTP quiche i zainicjuj klienta quiche 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);

Klient użyje kodowania binarnego HTTP, aby w pierwszym kroku utworzyć żądanie 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);

Klient szyfruje następnie żądanie Binary HTTP utworzone w powyższym kroku.


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

Po odebraniu odpowiedzi z usługi Relay klient ją odszyfruje. Odpowiedź będzie zawierać nagłówek odpowiedzi Content-Type w formacie ohttp-res.


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

Po odszyfrowaniu odpowiedzi OHTTP w podany niżej sposób zdekoduj dane wyjściowe za pomocą Binary 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(); }