אימות נתונים וזיהוי שינויים באמצעות סכומי ביקורת

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

מניעת פגיעה בנתונים באמצעות סכומי ביקורת

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

כדי להגן עליכם מפני פגיעה בנתונים, ב-Cloud Storage יש תמיכה בשימוש בסכומי ביקורת (checksum) מסוג CRC32C ו-MD5 כדי לאמת את תקינות הנתונים ולזהות שינויים בנתונים.

‫CRC32C היא שיטת האימות המומלצת לביצוע בדיקות תקינות. אימות באמצעות גיבוב מסוג MD5 נתמך בהעלאות של קובץ יחיד, אבל לא נתמך באובייקטים שמועלים במקטעים, כמו אובייקטים מורכבים ואובייקטים שמועלים באמצעות העלאה מרובת חלקים ב-API בפורמט XML.

בדיקות סיכום של כתיבת נתונים

בכתיבת אובייקטים, הלקוח מחשב את סיכום הביקורת של הקובץ המקומי ומצרף אותו לכותרות ה-HTTP של בקשת העלאת האובייקט. השרת מקבל את מטען הנתונים, מחשב את סיכום הביקורת שלו ומאמת את הנתונים על ידי השוואה בין שני סיכומי הביקורת אחרי שההעלאה מסתיימת. אם סיכומי הביקורת תואמים, האובייקט מאוחסן ב-Cloud Storage יחד עם סיכומי הביקורת שלו. אם סכומי הביקורת לא תואמים, בקשת הכתיבה נדחית עם השגיאה BadRequestException: 400.

אימות בצד השרת לכתיבת נתונים

Cloud Storage מבצע אימות בצד השרת במקרים הבאים:

  • כשמציינים את גיבוב MD5 או CRC32C של אובייקט בבקשת העלאה של אובייקט. מידע על סוגי העלאות של אובייקטים זמין במאמר העלאות של אובייקטים.

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

העלאות של בקשה יחידה (מדיה) ב-API בפורמט JSON

בהעלאות מדיה ב-API בפורמט JSON, אפשר לציין סכומי ביקורת בכותרת X-Goog-Hash של הבקשה. לדוגמה:

curl -X POST --data-binary @Desktop/dog-pic.jpeg \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: image/jpeg" \
    -H "X-Goog-Hash: crc32c=n03x6A==" \
    "https://storage.googleapis.com/upload/storage/v1/b/my-bucket/o?uploadType=media&name=dog-pic.jpeg"

העלאות מרובות חלקים באמצעות API בפורמט JSON

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

בדוגמה הבאה מצוין סיכום ביקורת (checksum)‏ CRC32C במטא-נתונים של האובייקט בחלק של מאגר הבקשות:

--separator_string
Content-Type: application/json; charset=UTF-8

{
"name":"my-document.txt",
"crc32c": "n03x6A=="
}

--separator_string
Content-Type: text/plain

This is a text file.
--separator_string--

בדוגמה הבאה מצוין סיכום ביקורת (checksum)‏ CRC32C במחרוזת הגבול השלישית של מאגר בקשות:

--separator_string
Content-Type: application/json; charset=UTF-8

{
"name":"my-document.txt"
}

--separator_string
Content-Type: text/plain

This is a text file.

--separator_string
Content-Type: application/json; charset=UTF-8

{ "crc32c": "n03x6A==" }
--separator_string--

העלאות שניתן להמשיך ב-API בפורמט JSON

בהעלאות שניתן להמשיך ב-API בפורמט JSON, אפשר לציין סכומי ביקורת בכותרת X-Goog-Hash של הבקשה הסופית שמשלימה את ההעלאה. לדוגמה:

curl -i -X PUT --data-binary @Desktop/dog-pic.jpeg \
      -H "Content-Length: 2000000" \
      -H "X-Goog-Hash: crc32c=n03x6A==" \
      "SESSION_URI"

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

העלאות באמצעות בקשה יחידה ב-API בפורמט XML

בהעלאות בבקשה יחידה באמצעות API בפורמט XML, אפשר לציין סכומי ביקורת בכותרת x-goog-hash של הבקשה.

לדוגמה:

curl -X PUT --data-binary @Desktop/dog-pic.jpeg \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: image/jpeg" \
    -H "x-goog-hash: crc32c=n03x6A==" \
    "https://storage.googleapis.com/my-bucket/dog-pic.jpeg"

העלאות של בקשה יחידה באמצעות API בפורמט XML מקבלות גם את כותרת Content-MD5 הרגילה של HTTP. פרטים נוספים זמינים במפרט של Content-MD5.

העלאות מרובות חלקים באמצעות API בפורמט XML

בהעלאות מרובות חלקים באמצעות API בפורמט XML, אפשר לציין סכום ביקורת לכל חלק בהעלאה. כדי לציין סכום ביקורת נפרד לחלק בהעלאה, צריך לכלול את הכותרת x-goog-hash בבקשה לחלק הספציפי הזה.

לדוגמה:

PUT /dog-pic.jpeg?partNumber=1&uploadId=ABgVH8 HTTP/1.1
Host: my-bucket.storage.googleapis.com
Content-Length: 1000000
x-goog-hash: crc32c=n03x6A==

אפשר להשתמש רק בסיכומי ביקורת (checksum) מסוג CRC32C כדי לאמת את התקינות של העלאות מרובות חלקים ב-API בפורמט XML. אין תמיכה בסכומי ביקורת מסוג MD5.

העלאות gRPC

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

בנוסף, פרוטוקול gRPC תומך בסכומי ביקורת לכל הודעה. WriteObject כל הודעה מכילה מקטעי נתונים של עד 2 מיביבייט, וכל מקטע יכול לכלול סכום ביקורת משלו. אפשר לציין סכומי ביקורת לכל הודעה במקום סכום ביקורת ברמת האובייקט או בנוסף אליו.

העלאות מורכבות במקביל

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

העתקה וכתיבה מחדש ב-Google Cloud CLI

ב-ה-CLI של gcloud, מתבצע אימות אוטומטי של נתונים שמועתקים לקטגוריה של Cloud Storage או ממנה. בפקודות cp, mv ו-rsync, ה-CLI של gcloud משתמש בסכומי ביקורת מסוג MD5 או CRC32C כדי לקבוע אם יש הבדל בין הגרסה של אובייקט שנמצא במקור לבין הגרסה שנמצאת ביעד. אם סיכום הביקורת (checksum) של נתוני המקור לא תואם לסיכום הביקורת (checksum) של נתוני היעד, ה-CLI של gcloud ימחק את העותק הלא תקין וידפיס הודעת אזהרה. זה קורה לעיתים רחוקות מאוד. אם זה קורה, צריך לנסות את הפעולה שוב.

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

‫Google Cloud CLI מתעלם מהדגל --content-md5 לאובייקטים שאין להם גיבוב MD5.

זיהוי שינויים ב-rsync

הפקודה gcloud storage rsync משווה בין סכומי ביקורת (checksums) בתרחישים הבאים כדי לקבוע אם לדלג על העברה:

  • המקור והיעד הם קטגוריות ב-Cloud Storage, ולאובייקט יש סיכום ביקורת (checksum) מסוג MD5 או CRC32C בשתי הקטגוריות.

  • לאובייקט אין זמן שינוי קובץ (mtime) במקור או ביעד.

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

mtimersyncאם אף אחד מהמקורות לא מספק ערך, המערכת תשתמש בערך ההמרה שמוגדר כברירת מחדל. לדוגמה, אי אפשר להשתמש ב-mtime או בסיכומי ביקורת (checksum) כשמשווים אובייקטים מורכבים לאובייקטים אצל ספק שירותי ענן שלא תומך ב-CRC32C, כי לאובייקטים מורכבים אין סיכומי ביקורת (checksum) מסוג MD5.

אימות בצד הלקוח לכתיבת נתונים

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

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

לקוח גרסה שתומכת בסיכומי ביקורת של כתיבת אובייקטים
ספריית הלקוח של Cloud Storage עבור ++C‎ ‫2.46 ואילך
ספריית הלקוח של Cloud Storage Go גרסה 1.60.0 ואילך
ספריית לקוח Java של Cloud Storage ‫2.62 ואילך
ספריית הלקוח של Cloud Storage Node.js ‫7.19.0 ואילך
ספריית הלקוח של Cloud Storage PHP גרסה 1.51.0 ואילך
ספריית לקוח Python של Cloud Storage גרסה 3.7.0 ואילך
ספריית הלקוח של Cloud Storage Ruby 1.60.0
ספריית הלקוח של Cloud Storage .NET גרסה 2.3.0 ואילך. מומלץ להשתמש בגרסה 4.15.0, שכוללת אימות של סכומי ביקורת בצד השרת.
חיבור ל-Cloud Storage
  • ‫3.0.18 ואילך לחיבור ל-Cloud Storage בגרסה 3.0.x
  • ‫3.1.14 ואילך לחיבור Cloud Storage בגרסה 3.1.x
  • גרסה 4.0.3 ואילך של המחבר 4.0.x Cloud Storage
‫Cloud Storage FUSE גרסה 3.8.0 ואילך
Google Cloud CLI

סכומי ביקורת לקריאות ולהורדות של נתונים

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

אימות בצד הלקוח לקריאה ולהורדה

כברירת מחדל, כל ערכות ה-SDK של ספריות הלקוח של Cloud Storage תומכות בחישוב של סכומי ביקורת להורדות ולקריאות של אובייקטים. בטבלה הבאה מופיע מידע על השבתת ההורדה של אובייקט או על קריאת סכומי הביקורת (checksums) לכל ערכת SDK של ספריית לקוח.

ספריית לקוח הוראות להשבתת סכומי ביקורת (checksum) של קריאה או הורדה של אובייקטים
ספריית הלקוח של Cloud Storage עבור ++C‎ בספריית הלקוח C++‎, כדי להשבית את אימות סיכום הביקורת, צריך להגדיר את DownloadChecksumValidationOption לערך ChecksumAlgorithm::kNone.
ספריית הלקוח של Cloud Storage Go בספריית הלקוח Go, משביתים את אימות סיכום הביקורת על ידי מתן אפשרויות קריאה בזמן האתחול. ‫Pass WithDisableReaderChecksum() כשמתקשרים NewReader או pass WithDisableMRDReadChecksum() כשמתקשרים אל NewMultiRangeDownloader.
ספריית לקוח Java של Cloud Storage כדי להשבית את האימות הפנימי של סיכום הביקורת CRC32C בנתיבי קריאה בספריית הלקוח של Java, צריך להעביר את מאפיין המערכת של JVM‏ -Dcom.google.cloud.storage.Hasher.read=disabled, שמשבית את הגיבוב הפנימי לקריאות. אם רוצים להשבית את בדיקת הסכום הכולל בכל הקריאות והכתיבות, צריך להשתמש ב--Dcom.google.cloud.storage.Hasher.default=disabled.
ספריית הלקוח של Cloud Storage Node.js בספריית הלקוח Node.js, כדי להשבית את אימות סכומי הבדיקה, צריך להעביר { validation: false } באובייקט של אפשרות ההגדרה שמועבר לקריאות של שיטת ההורדה.
ספריית הלקוח של Cloud Storage PHP בספריית הלקוח של PHP, כדי להשבית את אימות סיכום הביקורת (checksum) בנתיבי קריאה של API בפורמט JSON ו-API בפורמט XML, צריך להעביר את הערך 'validate' => false או 'validate' => 'none' במערך האפשרויות המשויך ($options['validate']) כשקוראים ל-methods של ההורדה.
ספריית לקוח Python של Cloud Storage בספריית הלקוח של Python, השבתת האימות של סכום הבדיקה תלויה בשיטת התקשורת של הלקוח: עבור לקוח JSON, מעבירים checksum=None (האפשרות הזו נתמכת ב-methods כמו download_to_file), ואילו עבור לקוח gRPC, מגדירים enable_checksum=False.
ספריית הלקוח של Cloud Storage Ruby בספריית הלקוח של Ruby, כדי להשבית את האימות של סכומי הביקורת, צריך להעביר ארגומנטים של מילות מפתח (checksum: או verify:) ישירות לשיטות ההורדה, ולהגדיר במיוחד את verify: none או verify: false.
ספריית הלקוח של Cloud Storage .NET בספריית הלקוח של ‎ .NET, כדי להשבית את אימות הצ'קסום, צריך להגדיר את המאפיין ChecksumValidation לערך DownloadValidationMode.Never באובייקט DownloadObjectOptions שמועבר לקריאות של שיטת ההורדה.

ביצוע בדיקות של תקינות הנתונים באובייקטים שהורדו או נקראו

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

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

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

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

  • תשובה שמכילה רק חלק מנתוני האובייקט: סוג התשובה הזה מתקבל לבקשות מסוג Range.

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

    אם האפליקציה שלכם צריכה לקרוא טווחי אובייקטים במקום אובייקטים מלאים בבת אחת, מומלץ להשתמש ב-gRPC. אחרת, מומלץ לשלוח בקשות לטווח חלקי של אובייקט רק כדי להפעיל מחדש את ההורדה של אובייקט שלם אחרי ההיסט האחרון שהתקבל, כי במקרה כזה אפשר לחשב ולאמת את סיכום הביקורת (checksum) כשההורדה המלאה מסתיימת.

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

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