הצפנה מאומתת עם מידע נלווה (AEAD) ב-GoogleSQL ל-BigQuery מאפשרת להגן על נתונים רגישים ברמת העמודה ולשלוט בפענוח ישירות בתוך שאילתות. באמצעות קישור של מידע מוצפן (ciphertext) לנתונים מאומתים נוספים, הצפנת AEAD מאמתת את תקינות הנתונים ומונעת שינויים לא מורשים או החלפה של המידע המוצפן.
רשימה מלאה של פונקציות SQL נתמכות מופיעה במאמר פונקציות הצפנה של AEAD.
המטרה של הצפנת AEAD
ב-BigQuery, הנתונים שלכם נשמרים בצורה בטוחה באמצעות הצפנה במנוחה. בנוסף, BigQuery תומך במפתחות הצפנה בניהול הלקוח (CMEK), שמאפשרים להצפין טבלאות באמצעות מפתחות הצפנה ספציפיים. עם זאת, במקרים מסוימים יכול להיות שתרצו להצפין ערכים ספציפיים בטבלה.
לדוגמה, אתם רוצים לשמור את הנתונים של כל הלקוחות שלכם בטבלה משותפת, ולהצפין את הנתונים של כל אחד מהלקוחות באמצעות מפתח אחר. יש לכם נתונים שפרוסים על פני כמה טבלאות, ואתם רוצים שתהיה לכם אפשרות לבצע "מחיקה באמצעות הצפנה". מחיקה באמצעות הצפנה (crypto-deletion או crypto-shredding) היא תהליך של מחיקת מפתח הצפנה, כדי שאי אפשר יהיה לקרוא את הנתונים שהוצפנו באמצעות המפתח הזה.
פונקציות הצפנה של AEAD מאפשרות ליצור קבוצות מפתחות שמכילות מפתחות להצפנה ולפענוח, להשתמש במפתחות האלה כדי להצפין ולפענח ערכים נפרדים בטבלה, ולבצע רוטציה של מפתחות בתוך קבוצת מפתחות.
קבוצות מפתחות
קבוצת מפתחות היא אוסף של מפתחות קריפטוגרפיים, שאחד מהם הוא המפתח הקריפטוגרפי הראשי והשאר, אם יש כאלה, הם מפתחות קריפטוגרפיים משניים. כל מפתח מקודד אלגוריתם להצפנה או לפענוח, את הסטטוס של המפתח (מופעל, מושבת או מושמד) ואת הבייטים של המפתח עצמו (אם הוא לא מושמד). המפתח הקריפטוגרפי הראשי קובע איך להצפין את הטקסט הפשוט של הקלט. המפתח הקריפטוגרפי הראשי אף פעם לא יכול להיות במצב מושבת. מפתחות קריפטוגרפיים משניים משמשים רק לפענוח, והם יכולים להיות במצב מופעל או מושבת. אפשר להשתמש בקבוצת מפתחות כדי לפענח כל נתון שהוצפן באמצעותה.
הייצוג של קבוצת מפתחות ב-GoogleSQL הוא כמאגר אחסון לפרוטוקולים מסוג google.crypto.tink.Keyset שעבר סריאליזציה ב-BYTES.
דוגמה
הדוגמה הבאה היא של קבוצת מפתחות AEAD, שמיוצגת כמחרוזת JSON, עם שלושה מפתחות.
{
"primaryKeyId": 569259624,
"key": [
{
"keyData": {
"typeUrl": "type.googleapis.com/google.crypto.tink.AesGcmKey",
"value": "GiDPhTp5gIhfnDb6jfKOT4SmNoriIJc7ah8uRvrCpdNihA==",
"keyMaterialType": "SYMMETRIC"
},
"status": "ENABLED",
"keyId": 569259624,
"outputPrefixType": "TINK"
},
{
"keyData": {
"typeUrl": "type.googleapis.com/google.crypto.tink.AesGcmKey",
"value": "GiBp6aU2cFbVfTh9dTQ1F0fqM+sGHXc56RDPryjAnzTe2A==",
"keyMaterialType": "SYMMETRIC"
},
"status": "DISABLED",
"keyId": 852264701,
"outputPrefixType": "TINK"
},
{
"status": "DESTROYED",
"keyId": 237910588,
"outputPrefixType": "TINK"
}
]
}
בדוגמה שלמעלה, המזהה של המפתח הקריפטוגרפי הראשי הוא 569259624, והוא המפתח הראשון שמופיע במחרוזת ה-JSON. יש שני מפתחות קריפטוגרפיים משניים, אחד עם המזהה 852264701 במצב מושבת, ואחד עם המזהה 237910588 במצב מושמד. כשפונקציית הצפנה של AEAD משתמשת במערך המפתחות הזה להצפנה, המידע המוצפן (ciphertext) שנוצר מקודד את המזהה של המפתח הקריפטוגרפי הראשי, 569259624.
כשפונקציית AEAD משתמשת בקבוצת המפתחות הזו לפענוח, הפונקציה בוחרת את המפתח המתאים לפענוח על סמך מזהה המפתח שמקודד במידע המוצפן (ciphertext). בדוגמה שלמעלה, ניסיון לפענח באמצעות מזהה המפתח 852264701 או 237910588 יגרום לשגיאה, כי מזהה המפתח 852264701 מושבת והמזהה 237910588 מושמד. אם תשחזרו את מזהה המפתח 852264701 למצב מופעל, תוכלו להשתמש בו לפענוח.
סוג המפתח קובע את מצב ההצפנה שבו משתמשים עם המפתח הזה.
הצפנה של טקסט פשוט יותר מפעם אחת באמצעות אותה קבוצת מפתחות בדרך כלל מחזירה ערכים שונים של מידע מוצפן (ciphertext) בגלל וקטורי אתחול (IV) שונים, שנבחרים באמצעות מחולל המספרים האקראיים לכאורה שסופק על ידי OpenSSL.
קבוצות מפתחות עטופות
אם אתם צריכים לנהל קבוצת מפתחות בצורה מאובטחת או להעביר אותה בערוץ לא מהימן, כדאי להשתמש בקבוצת מפתחות עטופה. כשעוטפים קבוצת מפתחות גולמיים, התהליך הזה מצפין את קבוצת המפתחות הגולמיים באמצעות מפתח Cloud KMS.
קבוצות מפתחות עטופות יכולות להצפין ולפענח נתונים בלי לחשוף את הנתונים של קבוצת המפתחות. יכול להיות שיש דרכים אחרות להגביל את הגישה לנתונים ברמת השדה, אבל קבוצות מפתחות עטופות מספקות מנגנון מאובטח יותר לניהול קבוצות מפתחות בהשוואה לקבוצות מפתחות גולמיות.
כמו קבוצות מפתחות, אפשר ומומלץ להחליף מדי פעם קבוצות מפתחות עטופות. קבוצות מפתחות ארוזות משמשות בפונקציות של הצפנת מעטפת AEAD.
הנה כמה פונקציות עם דוגמאות לקבוצת מפתחות עטופה:
-
KEYS.NEW_WRAPPED_KEYSET: יצירת קבוצת מפתחות עטופה חדשה. -
KEYS.ROTATE_WRAPPED_KEYSET: החלפת קבוצת מפתחות עטופה. -
KEYS.REWRAP_KEYSET: עטיפה מחדש של קבוצת מפתחות עטופה עם נתונים חדשים. -
KEYS.KEYSET_CHAIN: קבלת קבוצת מפתחות של Tink שמוצפנת באמצעות מפתח Cloud KMS.
תקן Advanced Encryption Standard (AES)
פונקציות הצפנה של AEAD משתמשות בהצפנה של תקן הצפנה מתקדם (AES). הצפנת AES מקבלת טקסט פשוט כקלט, יחד עם מפתח קריפטוגרפי, ומחזירה רצף מוצפן של בייטים כפלט. אפשר לפענח את רצף הבייטים הזה מאוחר יותר באמצעות אותו מפתח ששימש להצפנה. ב-AES משתמשים בגודל בלוק של 16 בייטים, כלומר הטקסט ללא הצפנה מטופל כרצף של בלוקים בגודל 16 בייטים. המידע המוצפן יכיל קידומת ספציפית ל-Tink, שמציינת את המפתח ששימש לביצוע ההצפנה. הצפנת AES תומכת במספר מצבי צופן בלוקים.
מצבי צופן בלוקים
שני מצבים של צופן בלוקים שנתמכים על ידי פונקציות הצפנה של AEAD הם GCM ו-CBC.
GCM
Galois/Counter Mode (GCM) הוא מצב להצפנת AES. הפונקציה ממספרת את הבלוקים ברצף, ואז משלבת את מספר הבלוק עם וקטור אתחול (IV). וקטור אתחול הוא ערך אקראי או אקראי לכאורה, שמהווה את הבסיס לאקראיות של נתוני הטקסט הפשוט. לאחר מכן, הפונקציה מצפינה את מספר הבלוק המשולב ואת ה-IV באמצעות AES. לאחר מכן, הפונקציה מבצעת פעולת XOR (או-בלעדי) לוגית ברמת הביט על תוצאת ההצפנה ועל הטקסט הפשוט, כדי ליצור את המידע המוצפן. במצב GCM נעשה שימוש במפתח קריפטוגרפי באורך 128 או 256 ביט.
מצב CBC
ב-CBC, הבלוקים "משורשרים" באמצעות פעולת XOR על כל בלוק של טקסט פשוט עם הבלוק הקודם של המידע המוצפן, לפני ההצפנה שלו. במצב CBC נעשה שימוש במפתח קריפטוגרפי באורך 128, 192 או 256 ביט. ב-CBC משתמשים בווקטור אתחול של 16 בייטים בתור הבלוק הראשוני, ומבצעים פעולת XOR על הבלוק הזה עם הבלוק הראשון של הטקסט הפשוט.
מצב CBC הוא לא סכימת AEAD במובן הקריפטוגרפי, כי הוא לא מספק תקינות נתונים. במילים אחרות, שינויים זדוניים בנתונים המוצפנים לא יזוהו, וזה פוגע גם בסודיות הנתונים. לכן לא מומלץ להשתמש ב-CBC, אלא אם יש צורך בכך מסיבות של תאימות לאחור.
נתונים נוספים
פונקציות הצפנה של AEAD תומכות בשימוש בארגומנט additional_data, שנקרא גם נתונים משויכים (AD) או נתונים מאומתים נוספים.
אפשר לפענח מידע מוצפן (ciphertext) רק אם מספקים לפענוח את אותם נתונים נוספים ששימשו להצפנה. לכן אפשר להשתמש בנתונים הנוספים כדי לקשר את המידע המוצפן להקשר.
לדוגמה, additional_data יכול להיות הפלט של CAST(customer_id AS STRING) כשמצפינים נתונים של לקוח מסוים.
כך אפשר לוודא שכשהנתונים מפוענחים, הם הוצפנו קודם באמצעות ה-customer_id הצפוי. כדי לפענח את ההצפנה, צריך להשתמש באותו ערך של additional_data. מידע נוסף זמין ב-RFC 5116.
פענוח
הפלט של AEAD.ENCRYPT הוא מידע מוצפן (ciphertext) BYTES. הפונקציות AEAD.DECRYPT_STRING או AEAD.DECRYPT_BYTES יכולות לפענח את המידע המוצפן הזה. הפונקציות האלה חייבות להשתמש בקבוצת מפתחות שמכילה את המפתח ששימש להצפנה. המפתח הזה חייב להיות במצב 'ENABLED'. הם גם צריכים להשתמש באותו additional_data ששימש להצפנה.
כשמשתמשים בקבוצת המפתחות לפענוח, המפתח המתאים נבחר לפענוח על סמך מזהה המפתח שמקודד במידע המוצפן.
הפלט של AEAD.DECRYPT_STRING הוא STRING בטקסט פשוט, והפלט של AEAD.DECRYPT_BYTES הוא BYTES בטקסט פשוט. AEAD.DECRYPT_STRING יכול לפענח מידע מוצפן (ciphertext) שמקודד ערך STRING, ו-AEAD.DECRYPT_BYTES יכול לפענח מידע מוצפן (ciphertext) שמקודד ערך BYTES. אם משתמשים באחת מהפונקציות האלה כדי לפענח מידע מוצפן (ciphertext) שמקודד את סוג הנתונים הלא נכון, למשל שימוש ב-AEAD.DECRYPT_STRING כדי לפענח מידע מוצפן (ciphertext) שמקודד ערך BYTES, זה גורם להתנהגות לא מוגדרת ועלול לגרום לשגיאה.
רוטציית מפתחות
המטרה העיקרית של רוטציה של מפתחות הצפנה היא לצמצם את כמות הנתונים שמוצפנים באמצעות מפתח מסוים, כך שאם מפתח מסוים ייחשף, התוקף יוכל לגשת לפחות נתונים.
רוטציה של קבוצת מפתחות כוללת:
- יצירת מפתח קריפטוגרפי ראשי חדש בכל קבוצת מפתחות.
- פענוח והצפנה מחדש של כל הנתונים המוצפנים.
הפונקציה KEYS.ROTATE_KEYSET או KEYS.ROTATE_WRAPPED_KEYSET מבצעת את השלב הראשון: הוספת מפתח קריפטוגרפי ראשי חדש לקבוצת מפתחות, ושינוי המפתח הקריפטוגרפי הראשי הישן למפתח קריפטוגרפי משני.
מפתחות Cloud KMS
כדי לאבטח את הנתונים שלכם עוד יותר, GoogleSQL תומך בפונקציות הצפנה של AEAD עם מפתחות Cloud KMS. שכבת ההגנה הנוספת הזו מצפינה את המפתח להצפנת נתונים (DEK) באמצעות מפתח להצפנת מפתחות הצפנה (KEK). ה-KEK הוא קבוצת מפתחות הצפנה סימטריים שמאוחסנת באופן מאובטח ב-Cloud Key Management Service, ומנוהלת באמצעות ההרשאות והתפקידים של Cloud KMS.
בזמן הרצת השאילתה, משתמשים בפונקציה KEYS.KEYSET_CHAIN כדי לספק את נתיב המשאב של ה-KEK ב-KMS ואת המידע המוצפן מה-DEK הארוז. BigQuery שולח קריאה ל-Cloud KMS כדי לבטל את האריזה של ה-DEK, ואז משתמש במפתח הזה כדי לפענח את הנתונים בשאילתה. הגרסה של ה-DEK שהאריזה שלו נפתחה מאוחסנת בזיכרון רק למשך השאילתה, ואז מושמדת.
מידע נוסף זמין במאמר הצפנה ברמת העמודה ב-SQL באמצעות מפתחות Cloud KMS.