בדף הזה מתואר פורמט הנתונים של Tink למפתחות ולפלט של פרימיטיבים. המסמכים מיועדים למומחים בהצפנה שרוצים להוסיף שפות נוספות ל-Tink, ולמנהלים של ספריות הצפנה אחרות ברמה גבוהה שרוצים מצב תואם ל-wire. התוכן לא מיועד לקהל הרחב.
סריאליזציה של קבוצת מפתחות
Tink משתמשת ב-Google protobuf כדי לבצע סריאליזציה של קבוצות המפתחות שלה.
- קבוצת מפתחות בינארית שעברה סריאליזציה היא פרוטוקול Keyset שעבר סריאליזציה ומוגדר ב-tink.proto. מאפיין הערך KeyData של מפתח הוא פרוטו מסוג serialized של סוג המפתח המתאים.
- קבוצת מפתחות שעברה סריאליזציה ב-JSON היא פרוטוקול Keyset שעבר סריאליזציה בפורמט JSON. שימו לב שהערך KeyData הוא עדיין פרוטו מסוג binary שעבר סריאליזציה.
- קבוצת מפתחות מוצפנת היא פרוטוקול EncryptedKeyset סדרתי שמוגדר ב-tink.proto. הוא מכיל קבוצת מפתחות מוצפנת בינארית שעברה סריאליזציה ובאופן אופציונלי גם מטא-נתונים לא מוצפנים של KeysetInfo.
קידומת הפלט של Tink
רוב הפרימיטיבים של Tink תומכים בקידומת פלט של 5 בייט שכוללת:
- גרסה של בייט אחד:
0x01 - רמז למפתח באורך 4 בייט: זהו מזהה המפתח שבו נעשה שימוש.
יכול להיות שחלק מהמפתחות מדור קודם תומכים גם בבייט הגרסה 0x00.
חשוב לזכור שהקידומת הזו לא מאומתת ואי אפשר להסתמך עליה למטרות אבטחה. Tink משתמש בו כרמז כדי לזרז את הפענוח או האימות.
AEAD
באופן כללי, Tink מעצב טקסטים מוצפנים של AEAD כך:
prefix || IV || ciphertext || tag
אלא אם צוין אחרת ב-RFC המתאים. prefix הוא ריק או שהוא קידומת פלט של Tink באורך 5 בייט.
AES-CTR-HMAC
ב-AES-CTR-HMAC, Tink מחשב את ה-MAC עם נתונים משויכים (AD) באופן הבא:
AD || IV || ciphertext || bitlen(AD)
כאשר bitlen(AD) הוא אורך ה-AD בביטים, שמיוצג כמספר שלם לא מסומן ב-64 ביטים בשיטת big-endian. סכמת ה-HMAC הזו מבוססת על הטיוטה של AES-CBC-HMAC מאת
Mcgrew.
Deterministic AEAD
Tink מטמיע את RFC 5297 עבור AES-SIV, ומציב את וקטור האתחול הסינתטי (SIV) בתחילת הטקסט המוצפן. יכול להיות שהפרימיטיב יוסיף קידומת של 5 בייט לפלט של Tink.
למרות שתקן RFC 5297 תומך ברשימה של נתונים משויכים, Tink תומך רק בנתון משויך אחד בדיוק, שמתאים לרשימה עם רכיב אחד בתקן RFC 5297. נתונים משויכים ריקים הם רשימה עם אלמנט ריק אחד, ולא רשימה ריקה.
סטרימינג AEAD
מידע נוסף זמין במאמרים בנושא AES-CTR HMAC ו-AES-GCM-HKDF.
הצפנת מעטפות
הצפנת מעטפת מצפינה את הנתונים באמצעות מפתח להצפנת נתונים DEK באמצעות פרימיטיבים של AEAD ב-Tink. ההצפנה פועלת באופן הבא:
- נוצר
DEKחדש באמצעות תבנית מפתח נתונה (או פרמטרים של מפתח). - המחרוזת
DEKעוברת סריאליזציה למחרוזת בייטים. פורמט הסריאליזציה של מאגר אחסון לפרוטוקולים של מפתח ההצפנה. לדוגמה, זוהי הודעתAesGcmKeyמאגר אחסון לפרוטוקולים שעברה סריאליזציה ומוגדרת ב-aes_gcm.proto עבור DEK מסוג מפתח AES GCM. במאמר סריאליזציה של מאגר אחסון לפרוטוקולים מוסבר איך לבצע סריאליזציה של מאגר אחסון לפרוטוקולים. - המחרוזת
DEKעוברת הצפנה על ידי ספק חיצוני (לדוגמה, GCP) והופכת למחרוזתencrypted DEK. - המפתח
DEKמשמש להצפנת הטקסט ללא הצפנה עם הנתונים המשויכים ל-ciphertext. לכן,ciphertextהוא בדיוק באותו פורמט כמו הפרימיטיב AEAD שמתאים ל-DEK.
פורמט הפלט של הצפנת מעטפה הוא כזה:
encrypted DEK length || encrypted DEK || ciphertext
הערך encrypted DEK length הוא 4 בייטים, שבהם מאוחסן האורך של encrypted DEK
כמספר שלם מסוג big-endian של 32 ביט.
MAC
Tink פועל בהתאם לתקני ה-RFC המתאימים. יכול להיות שפרימיטיבים יוסיפו לתג קידומת של 5 בייט של פלט Tink.
קבוצת PRF
Tink פועל בהתאם לתקני ה-RFC המתאימים. שימו לב: עבור PRF, סוג המפתח שונה מסוג מפתח ה-MAC של אותו אלגוריתם, כי הוא לא כולל את אורך הפלט. מפתחות PRF אף פעם לא מוסיפים קידומת פלט של Tink. כך מוודאים שהפלט הוא אכן PRF.
הצפנה היברידית
פורמט החיבור הכללי להצפנה היברידית ב-Tink הוא:
prefix || encapsulated_key || encrypted_data
prefix ריק או שהוא תחילית פלט של Tink באורך 5 בייט. כל סוג מפתח מכיל את המידע על מספר הבייטים לניתוח, ועל אופן הניתוח של הבייטים האלה מ-encapsulated_key.
HPKE (הצפנה היברידית של מפתח ציבורי)
Tink פועל לפי תקן ה-HPKE שמוגדר ב-RFC 9180. חבילת הצפנה של HPKE כוללת את שלושת הפרימיטיבים הבאים.
- מנגנון אנקפסולציה של מפתח (KEM)
- פונקציית נגזרת מפתח (KDF)
- הצפנה מאומתת עם נתונים משויכים (AEAD)
תקן HPKE לא מגדיר פורמט כללי של נתונים ב-RFC 9180, סעיף 10. ההטמעה של HPKE ב-Tink משתמשת בערכים הבאים של encapsulated_key ו-encrypted_data.
encapsulated_key- המפתח הציבורי הסדרתי של השולח
- מוגדר כ-
encב-RFC 9180, סעיף 4.1 - הפורמט נקבע לפי ה-KEM הספציפי של HPKE שבו נעשה שימוש
encrypted_data- טקסט מוצפן ותג (כלומר,
ciphertext || tagללא וקטור האתחול) - מוגדר כ-
ctבRFC 9180, סעיף 4 - הפורמט נקבע לפי ה-AEAD הספציפי של HPKE שבו נעשה שימוש
- טקסט מוצפן ותג (כלומר,
X25519 Diffie-Hellman-based KEM
ב-X25519 DHKEMs, הערך enc הוא המפתח הציבורי של שולח Diffie-Hellman בגודל 32 בייט.
ECIES-AEAD-HKDF
ביישום של Tink ל-ECIES-AEAD-HKDF, encapsulated_key הוא הפלט של מנגנון האנקפסולציה של המפתח (KEM) ו-encrypted_data הוא הפלט של מנגנון האנקפסולציה של הנתונים (DEM).
KEM
בהתאם לסוג המפתח, Tink משתמשת בנקודות של עקומות אליפטיות דחוסות ולא דחוסות, בהתאם לתקני הקידוד RFC 8422/ANSI.X9-62.2005. בנקודות לא דחוסות, אחרי הבייט 0x04 מופיעים הקואורדינטות x ו-y כמספרים שלמים בגודל קבוע. במקרה של קואורדינטות דחוסות, נעשה שימוש בבייט 0x02 או 0x03 ובקואורדינטה x כמספר שלם בגודל קבוע. X25519,
נעשה שימוש בהגדרה של RFC 7748 (קואורדינטה x כמספר שלם בגודל קבוע).
DEM
במקרה של encrypted_data, Tink משתמש באותו פורמט כמו AEAD. זה כולל ציון של IV.
גזירת מפתח
קודם מחשבים את קואורדינטת ה-x x_ss של הנקודה המשותפת. המפתח של AEAD מוגדר כך:
HKDF(ikm = encapsulated_key || x_ss, salt = salt_of_key, info = context_info, length = dem_key_size)
כאשר encapsulated_key הוא הפלט המלא של KEM בבייטים.
חתימות דיגיטליות
Tink פועל בהתאם לתקני ה-RFC המתאימים. יכול להיות שפרימיטיבים יוסיפו לתג שנוצר קידומת של 5 בייט של פלט Tink.
ECDSA
בהתאם לשדה EcdsaSignatureEncoding במפתח, הפורמט של חתימת ECDSA הוא IEEE P1363 או ASN.1 DER.
הפורמט של החתימה IEEE P1363 הוא r || s, כאשר r ו-s מרופדים באפסים ויש להם את אותו גודל בבייטים כמו הסדר של העקומה. לדוגמה, עבור עקומת NIST P-256, הערכים r ו-s מרופדים באפסים עד 32 בייטים.
חתימת ה-DER מקודדת באמצעות ASN.1:
ECDSA-Sig-Value :: = SEQUENCE { r INTEGER, s INTEGER }
באופן ספציפי, הקידוד הוא:
0x30 || totalLength || 0x02 || r's length || r || 0x02 || s's length || s
Tink פועל בהתאם לשיטות המומלצות לאימות חתימות, ומקבל רק חתימות ECDSA עם קידוד DER (חתימות עם קידוד BER חלופיות לא תקפות).
כך אפשר למנוע מתקפות של שינוי חתימה, שמשפיעות לעיתים קרובות על מערכות של מטבעות קריפטוגרפיים.
External Mu ML-DSA prehash values
הפרימיטיב Prehash הופך הודעה לערך prehash, שפרימיטיב SignPrehash חותם עליו. ב-ML-DSA במצב External Mu, כפי שמתואר ב-RFC 9881, ערך ה-prehash הוא 69 בייט עם הפריסה הבאה:
0xff || key_id (4 bytes, big-endian) || mu (64 bytes)
-
muהוא נציג ההודעה של ML-DSA, שמחושב כ-SHAKE256(tr || 0x00 || 0x00 || message, 64), כאשרtrהוא הגיבוב (hash) של המפתח הציבורי באורך 64 בייט,0x00הראשון הוא מפריד הדומיין FIPS 204 עבור ML-DSA טהור, ו-0x00השני הוא האורך של מחרוזת ההקשר (context) (הריקה). מכיוון ש-trנגזר מהמפתח הציבורי, הוא קשור למפתח הזה באופן קריפטוגרפי – אבל כדי לבדוק את הקשר הזה צריך את ההודעה המקורית.mu - הקידומת בת 5 הבייטים היא מסגור של Tink, ולא חלק מ-
mu. היא משייכת את ערך הגיבוב המוקדם למפתח ספציפי אחד, כדי שהפונקציה SignPrehash תדע באיזה מפתח לחתום ותוכל לדחות ערך גיבוב מוקדם שאין לה מפתח בשבילו. הקידומת היא מטא-נתונים רגילים, ולא מתבצעת הצפנה: כל אחד יכול לשנות אותה.
החתימה דוחה כל קלט שלא בדיוק 69 בייט, שלא מתחיל ב-0xff, או שמזהה המפתח שלו לא תואם למפתח מופעל בערכת המפתחות שלו.