חתימות

חתימות הן שיטה אחת לאימות בקשות שנשלחות ל-Cloud Storage API בפורמט XML. משתמשים בחתימות כשעובדים למשל עם כתובות URL חתומות או עם טופסי HTML. הדף הזה רלוונטי לחתימות שנוצרות באמצעות תהליך החתימה V4, שהוא התהליך המומלץ ליצירת חתימות.

חתימות הן ספציפיות ל-API בפורמט XML של Cloud Storage ושונות מאסימוני OAuth 2.0. אפשר להשתמש באסימוני OAuth 2.0 גם עם API בפורמט XML, והם רלוונטיים יותר באופן כללי לשירותים שונים, כולל API בפורמט JSON של Cloud Storage. Google Cloud

סקירה כללית

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

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

ב-Cloud Storage, חובה להשתמש בחתימות כשעובדים עם:

בנוסף, אפשר להשתמש בחתימות בכותרת Authorization של בקשות API בפורמט XML.

השימוש בחתימות בבקשות ישירות יעיל כשמבצעים מיגרציות פשוטות מ-Amazon S3. אבל בתהליך האימות לבקשות ישירות מומלץ להשתמש באסימונים של OAuth 2.0.

מבנה

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

תרחיש לדוגמה מפתח החתימה מידע על הבקשה
טופס HTML עם מפתח RSA שימוש ישיר במפתח פרטי של RSA מסמך מדיניות בקידוד Base64
טופס HTML עם מפתח HMAC מופק מהסוד של מפתח ה-HMAC מסמך מדיניות בקידוד Base64
כתובת URL חתומה או כותרת חתומה עם מפתח RSA שימוש ישיר במפתח פרטי של RSA מחרוזת לחתימה
כתובת URL חתומה או כותרת חתומה עם מפתח HMAC מופק מהסוד של מפתח ה-HMAC מחרוזת לחתימה

מחרוזת לחתימה

מחרוזת לחתימה (string-to-sign) כוללת מטא-מידע על הבקשה וגיבוב (hash) של הבקשה הקנונית שעליה אתם רוצים לחתום.

מבנה

'מחרוזת לחתימה' צריכה להיות בקידוד UTF-8 ובמבנה הבא, כולל מעבר לשורה חדשה אחרי כל אחד מהרכיבים:

SIGNING_ALGORITHM
ACTIVE_DATETIME
CREDENTIAL_SCOPE
HASHED_CANONICAL_REQUEST

האלגוריתם של החתימה

הערך שבו משתמשים ל-SIGNING_ALGORITHM תלוי בסוג המפתח שבו משתמשים ובתוספים שבהם משתמשים לכותרות או לפרמטרים של השאילתות:

תרחיש לדוגמה הערך של SIGNING_ALGORITHM
תוספי x-goog-* ומפתח RSA GOOG4-RSA-SHA256
תוספי x-goog-* ומפתח HMAC GOOG4-HMAC-SHA256
תוספי x-amz-* ומפתח HMAC AWS4-HMAC-SHA256

יחידת תוקף של תאריך-שעה

התאריך והשעה שבהם אפשר להשתמש בחתימה, בפורמט הבסיסי YYYYMMDD'T'HHMMSS'Z' לפי ISO 8601.

  • בכתובות URL חתומות, אפשר להשתמש בחתימה החל מ-15 דקות לפני התאריך והשעה שמצוינים ביחידת התוקף, ועד לתאריך התפוגה שציינתם. התאריך והשעה שביחידת התוקף צריכים להתאים לפרמטר של מחרוזת השאילתה X-Goog-Date של כתובת ה-URL החתומה, והיום צריך להיות היום שציינתם בהיקף ההרשאות של פרטי הכניסה.

  • בבקשות עם כותרות חתומות, אפשר להשתמש בחתימה החל מ-15 דקות לפני התאריך והשעה שמצוינים ביחידת התוקף, ועד 15 דקות לאחר התאריך והשעה האלה. התאריך והשעה שביחידת התוקף צריכים להתאים לכותרת x-goog-date של הבקשה באמצעות החתימה, והיום צריך להיות היום שציינתם בהיקף ההרשאות של פרטי הכניסה.

היקף ההרשאות של פרטי הכניסה

היקף ההרשאות של פרטי הכניסה של הבקשה.

גיבוב (hash) של הבקשה הקנונית

גיבוב SHA-256 עם קידוד הקסדצימלי של בקשה קנונית. כדי ליצור ערך גיבוב של הבקשה הקנונית, השתמשו בפונקציית הגיבוב (hashing) SHA-256. בשפת התכנות שלכם צריכה להיות ספרייה ליצירת גיבובי SHA-256. ערך גיבוב לדוגמה נראה כך:

436b7ce722d03b17d3f790255dd57904f7ed61c02ac5127a0ca8063877e4e42c

דוגמה

בדוגמה הבאה רואים תבנית נכונה של 'מחרוזת לחתימה'. השורות החדשות מופיעות כשורות חדשות בפועל ולא כ-\n:

GOOG4-RSA-SHA256
20191201T190859Z
20191201/us-central1/storage/goog4_request
54f3076005db23fbecdb409d25c0ccb9fb8b5e24c59f12634654c0be13459af0

מסמך מדיניות

מסמך המדיניות מגדיר מה יכולים המשתמשים שיש להם גישה לטופס ה-HTML המתאים להעלות ל-Cloud Storage. מסמך המדיניות מספק הרשאה כדי לוודא שטופס ה-HTML יכול להעלות קבצים לקטגוריית היעד. באמצעות מסמכי מדיניות ניתן לאפשר למבקרים באתר להעלות קבצים ל-Cloud Storage.

את מסמך המדיניות יוצרים ב-JavaScript Object Notation ‏(JSON). מסמך המדיניות צריך להיות בקידוד UTF-8 ובקידוד Base64. מסמך המדיניות מורכב מהמקטעים הבאים:

הערך תיאור
expiration תאריך ושעת התפוגה של מסמך המדיניות, בפורמט הבסיסי YYYYMMDD'T'HHMMSS'Z' של ISO 8601. מסמך מדיניות שתוקפו פג יוצר תקלה בטופס ה-HTML.
conditions מערך התנאים שכל העלאה צריכה לעמוד בהם.

המקטע conditions חייב לכלול:

  • הצהרת תנאי לכל שדה שבו משתמשים בטופס ה-HTML, חוץ מאשר לשדות x-goog-signature, file ו-policy.

  • הצהרת תנאי "bucket", גם אם לא משתמשים בשדה הקטגוריה בטופס ה-HTML.

כדי להשתמש בכמה הצהרות תנאי לאותו שדה צריך ליצור טופס HTML נפרד לכל אחת מהן. בהצהרות התנאי אפשר להשתמש בשלושה סוגים של תנאים:

  • התאמה מדויקת

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

    {"field" : "value"}
    ["eq", "$field", "value"]

    כל השדות הרלוונטיים בטופס HTML, מלבד Content-Length, יכולים להשתמש בהתאמה מדויקת.

  • מתחיל ב-

    אם הערך בשדה צריך להתחיל בקידומת מסוימת, משתמשים בתנאי starts-with עם התחביר הבא:

    ["starts-with", "$field", "value"]

    אם אין הגבלות על ערך בשדה מסוים, משתמשים בתנאי starts-with עם התחביר הבא:

    ["starts-with", "$field", ""]

    כל השדות הרלוונטיים בטופס HTML, מלבד Content-Length, יכולים להשתמש בתנאי starts-with.

  • הטווח של אורך התוכן

    התנאי הזה מציין טווח של ערכים קבילים לשדה Content-Length. מגדירים את התנאי הזה באמצעות התחביר הבא:

    ["content-length-range", min_range, max_range]

דוגמה

דוגמה למסמך מדיניות:

{"expiration": "2020-06-16T11:11:11Z",
 "conditions": [
  ["starts-with", "$key", ""],
  {"bucket": "travel-maps"},
  {"success_action_redirect": "http://www.example.com/success_notification.html"},
  ["eq", "$Content-Type", "image/jpeg"],
  ["content-length-range", 0, 1000000],
  {"x-goog-algorithm": "GOOG4-RSA-SHA256"},
  {"x-goog-credential": "example_account@example_project.iam.gserviceaccount.com/20191102/us-central1/storage/goog4_request"},
  {"x-goog-date": "20191102T043530Z"}
  ]
}

במסמך המדיניות הזה מוגדרים התנאים הבאים:

  • תוקף הטופס יפוג ב-16 ביוני 2020 בשעה 11:11:11 (שעון UTC).
  • שם הקובץ יכול להתחיל בכל תו חוקי.
  • צריך להעלות את הקובץ לקטגוריה travel-maps.
  • אם ההעלאה תתבצע בהצלחה, המשתמש יופנה אוטומטית לכתובת http://www.example.com/success_notification.html.
  • הטופס מאפשר להעלות רק תמונות.
  • המשתמש לא יכול להעלות קובץ שגודלו עולה על 1MB.

היקף ההרשאות של פרטי הכניסה

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

DATE/LOCATION/SERVICE/REQUEST_TYPE

היקף ההרשאות של פרטי הכניסה כולל את הרכיבים:

  • DATE: התאריך שבו אפשר להשתמש בחתימה, בפורמט YYYYMMDD.
  • LOCATION: במשאבי Cloud Storage, אפשר להשתמש בכל ערך של LOCATION. הערך המומלץ הוא המיקום שמשויך למשאב שעליו חלה החתימה. לדוגמה, us-central1. הפרמטר הזה קיים כדי לשמור על תאימות עם Amazon S3.
  • SERVICE: שם השירות. ברוב המקרים, כשניגשים למשאבים של Cloud Storage, הערך הוא storage. כשמשתמשים בתוספי x-amz של Amazon S3, הערך הזה הוא s3.
  • REQUEST_TYPE: סוג הבקשה. ברוב המקרים, כשניגשים למשאבים של Cloud Storage, הערך הוא goog4_request. כשמשתמשים בתוספי x-amz של Amazon S3, הערך הזה הוא aws4_request.

לדוגמה, היקף ההרשאות של פרטי הכניסה נראה כך:

20191102/us-central1/storage/goog4_request

כשמשתמשים ב'מחרוזת לחתימה' עם תוספי x-amz, היקף ההרשאות של פרטי הכניסה נראה כך:

20150830/us-east1/s3/aws4_request

חתימה

כדי ליצור חתימה, משתמשים באלגוריתם חתימה, שנקרא גם פונקציית גיבוב (hash) קריפטוגרפית, כדי לחתום את ה'מחרוזת לחתימה' או את מסמך המדיניות. אלגוריתם החתימה יוצר תקציר הודעה, שצריך להיות מקודד בפורמט הקסדצימלי כדי ליצור את החתימה הסופית. אלגוריתם החתימה שבו משתמשים תלוי בסוג מפתח האימות שיש לכם:

מפתח אימות האלגוריתם של החתימה מפתח החתימה
מפתח RSA RSA-SHA256 שימוש ישיר במפתח פרטי של RSA
מפתח HMAC HMAC-SHA256 מופק מהסוד של מפתח ה-HMAC

אפשר להפעיל את אלגוריתם החתימה RSA-SHA256 באמצעות השיטה IAM signBlob. כלים כמו ה-CLI של gcloud ורוב Google Cloud ספריות הלקוח מאפשרים ליצור כתובות URL חתומות באמצעות השיטה signBlob.

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

הפקת מפתח החתימה ממפתח HMAC

כשחותמים באמצעות מפתח HMAC, צריך ליצור מפתח חתימה בקידוד UTF-8, שנגזר מהסוד של מפתח ה-HMAC. המפתח שנגזר הוא ספציפי לתאריך, למיקום, לשירות ולסוג הבקשה שמשויכים לבקשה שלכם. הקוד המדומה הבא מראה איך להפיק את מפתח החתימה:

key_date = HMAC-SHA256("PREFIX" + HMAC_KEY_SECRET, "DATE")
key_region = HMAC-SHA256(key_date, "LOCATION")
key_service = HMAC-SHA256(key_region, "SERVICE")
signing_key = HMAC-SHA256(key_service, "REQUEST_TYPE")

הקוד המדומה כולל את הרכיבים הבאים:

  • PREFIX: ברוב המקרים, כשניגשים למשאבים של Cloud Storage, הערך הוא GOOG4. כשמשתמשים בתוספי x-amz של Amazon S3, הערך הזה הוא AWS4.
  • HMAC_KEY_SECRET: הסוד למפתח HMAC שבו אתם משתמשים כדי לשלוח את הבקשה ולחתום.
  • DATE, LOCATION, SERVICE, REQUEST_TYPE: הערכים האלה צריכים להתאים לערכים שמצוינים בהיקף ההרשאות של פרטי הכניסה.

אחרי שגוזרים את מפתח החתימה, יוצרים את החתימה באופן מקומי באמצעות שפת תכנות שכוללת ספרייה עם אלגוריתם החתימה HMAC-SHA256.

אחרי החתימה

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

דוגמה

הקוד הבא הוא קוד מדומה לחתימת מסמך מדיניות:

EncodedPolicy = Base64Encode(PolicyDocument)
MessageDigest = SigningAlgorithm(SigningKey, EncodedPolicy)
Signature = HexEncode(MessageDigest)

הקוד הבא הוא קוד מדומה לחתימת 'מחרוזת לחתימה':

MessageDigest = SigningAlgorithm(SigningKey, StringToSign)
Signature = HexEncode(MessageDigest)

המאמרים הבאים