Overview

API של Oblivious HTTP Gateway API

הערה: המסמך הזה עדיין נמצא בפיתוח. צפויים שיפורים בעתיד הקרוב.

API Oblivious HTTP Gateway API של גלישה בטוחה הוא API לשמירה על פרטיות שמבוסס על פרוטוקול IETF RFC שנקרא Oblivious HTTP, RFC 9458.

סקירה כללית

'גלישה בטוחה' Oblivious HTTP Gateway API הוא שירות של Google שמאפשר לאפליקציות לקוח לבדוק כתובות URL מול רשימות ש-Google מעדכנת באופן קבוע, שכוללות משאבי אינטרנט לא בטוחים, עם אמצעי הגנה נוספים על הפרטיות.

ניתן לעשות זאת באמצעות פרוטוקול פשוט שנקרא Oblivious HTTP, או בקיצור OHTTP. זהו פרוטוקול ללא שמירת מצב שיכול לשמש לקוחות של גלישה בטוחה כדי לגשת אל ממשקי ה-API של גרסה V5 של הגלישה הבטוחה של Google, וכך לקבל הגנות חזקות וכיסוי מוגבר, מבלי לפגוע בפרטיות המשתמשים.

הערה: לא ניתן לגשת באמצעות השירות הזה לממשקי ה-API של גרסה 4 של הגלישה הבטוחה של Google.

פרוטוקול HTTP של Oblivious לגלישה בטוחה

פרוטוקול RFC

Oblivious HTTP הוא פרוטוקול קליל המוגדר ב-RFC 9458, המשמש להצפנה ולשליחה של הודעות HTTP מלקוח לשרת יעד. אפשרות זו משתמשת בשירות ממסר מהימן באופן שמפחית את השימוש של שרת היעד במטא-נתונים, כמו כתובת IP ופרטי חיבור, לצורך זיהוי לקוחות, ומספק פרטיות ואבטחה מעל לפרוטוקול HTTP/S פשוט. הפרוטוקול משתמש ב-Binary HTTP, שמוגדר ב-RFC 9292, כדי לקודד/לפענח בקשות/תגובות HTTP.

ברמה הכללית, ממסר עומד בין המשאב 'לקוח' ו-'Gateway' שמעביר את תעבורת הנתונים של לקוחות בשרתי proxy על ידי הסרת כל מזהי הלקוח, כולל מאפיינים רגישים לפרטיות, כמו כתובות IP, תוך אנונימיזציה יעילה של בקשות HTTP נכנסות לשירות Gateway. היתרון הנוסף של OHTTP הוא שכל הבקשות מוצפנות מקצה לקצה, והמשמעות היא ששאילתות גלישה בטוחה של לקוחות (כלומר גיבובים קטועים של ביטויים של כתובות URL) לא גלויות לממסר. בפוסט בבלוג אפשר לראות הטמעה לדוגמה ב-Chrome.

הארכיטקטורה הכוללת של השירות.
איור: זרימת OHTTP.

הלקוחות יכולים לבחור כל ספק ממסר (למשל, במהירות) לצורך שילוב עם השירות. הממסר חייב להשתמש באימות Oauth 2.0 עם היקף ההרשאה הבא כדי לגשת לשירות.


// OAuth Authorization scope: https://www.googleapis.com/auth/3p-relay-safe-browsing
נקודות קצה ל-API
מפתח ציבורי מסוג OHTTP

נקודת הקצה הזו תספק הגדרה של מפתח ציבורי מסוג OHTTP כפי שצוין ב-RFC 9458, שבו הלקוח ישתמש להצפנת בקשת OHTTP.


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

מפתח ה-API שצוין למעלה אינו הכרחי לגמרי. השרת לא משנה את המפתח הציבורי של OHTTP על סמך מפתח ה-API שסופק. לקוחות יכולים לבדוק עובדה זו על ידי שימוש במפתחות API תקפים שונים כדי לגשת לנקודת הקצה הזו, או לא להשתמש בכלל במפתחות API, ולבדוק שהתגובה אכן מכילה את אותו מפתח ציבורי מסוג OHTTP. עם זאת, כדי להקל על ניפוי הבאגים, מומלץ להשתמש במפתח API. מפתח ה-API הזה מאפשר ללקוחות להציג נתונים סטטיסטיים כמו מספר הבקשות במסוף Google Cloud. אם הלקוח מתכוון לספק מפתח API, כדאי לעיין במסמכים האלה להגדרת מפתחות API.

כפי שצוין בסעיף המלצות בנושא פרטיות, כדי לעמוד ביעדים של עקביות מפתחות, אנחנו ממליצים לספקי לקוחות להגדיר תשתית של הפצה מרכזית של מפתחות כדי לאחזר את המפתח מנקודת קצה זו ולהפיץ אותו לאפליקציות של הלקוחות שלהם.

בהתאם להנחיות לניהול מפתחות, המפתחות עוברים רוטציה באופן קבוע בשרת. הלקוחות צריכים לרענן את המפתח, כלומר לאחזר ולעדכן את העותק המקומי של המפתח מדי פעם, כדי למנוע כשלים בפענוח.

על הלקוחות לרענן (לאחזר ולעדכן) את המפתח הציבורי פעם ביום. אם מנגנון הפצה מרכזי נמצא בשימוש, המנגנון הזה צריך להקפיד לאחזר ולהפיץ את המפתחות פעם ביום.

בקשה ארוזה של OHTTP

נקודת הקצה (endpoint) הזו תפעיל את בקשת ה-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 לגבי בניית בקשה של גלישה בטוחה) באמצעות פרוטוקול Binary HTTP, RFC 9292.

ספריות לקוח

ל-Google Quiche יש הטמעות בצד הלקוח גם בפרוטוקול OHTTP וגם בפרוטוקול BHTTP. אנחנו ממליצים ללקוחות להשתמש בספריות האלה. אפשר להיעזר בפסאודו-קוד שבהמשך כדי ליצור בקשות OHTTP כדי לגשת ל-API.

דוגמה להטמעה בצד הלקוח

לקוחות מאחזרים את המפתח הציבורי של Oblivious HTTP מנקודת הקצה של מפתח ציבורי. לאחר מכן, צריך להפעיל את הגדרת מפתח ה-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);

הלקוח ישתמש בקידוד Binary 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();

אחרי שהתשובה תתקבל ממסר, הלקוח יפענח את התשובה. התשובה תכלול את כותרת התגובה 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, צריך לפענח את הפלט באמצעות 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(); }