עקביות

חשוב ש-Tink יתנהג "אותו הדבר" בכל שפות התכנות. התפיסה הזו אינה פשוטה, אך הדבר החשוב ביותר הוא:

כדי לשמור על העקביות, ב-Tink משתמשת בבדיקות בשפות שונות, שנמצאות במאגר של GitHub בכל השפות. בדיקות אלה מאמתות את העקביות ואת יכולת הפעולה ההדדית של שפות שונות.

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

הקשר

ברמה גבוהה, Tink מספקת את ממשקי ה-API הבאים:

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

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

  • Primitive creation: Tink מספקת API ליצירת ממשק לפרימיטיב ממערך מפתחות. לדוגמה, כדי ליצור אובייקט Aead ממערך מפתחות ב-Java, המשתמש קורא ל-keysetHandle.getPrimitive(Aead.class, config).

  • Primitive usage: הממשק שנוצר בשלב היצירה הפשוט מספק API לביצוע פעולות קריפטוגרפיות.

יש שתי שאלות חשובות שכדאי לשאול לגבי ממשקי ה-API האלה:

  • יצירה: האם אפשר ליצור את הפרימיטיב ממערך המפתחות הזה בשפה, במערך מפתחות, שפה ופרימיטיב נתונים עם סדרה מסוימת?

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

חשוב לציין ש-Tink לא מספק עקביות בניתוח של ערכת מפתחות. לדוגמה, ייתכן שהפונקציה Tink C++

  • מנתח בהצלחה ערכות מפתחות שמכילות מפתחות CHACHA20-POLY1305, למרות שפעולות CHACHA20-POLY1305 AEAD לא מוטמעות ב-Tink;
  • מנתח בהצלחה ערכות מפתחות עם מפתחות בעלי בייט אחד, והם ייכשלו בכל הפעולות הקריפטוגרפיות.

התנהגויות כאלה עשויות להשתנות בגרסאות משניות.

עקביות בהערכה

עקביות בהערכה חשובה יותר מכל עקביות בתהליך היצירה: אם AEAD ב-Java לא יכול לפענח את ההצפנה של AEAD ב-C++ , למשתמשים יש בעיה חמורה.

באופן כללי, המטרה של טינק היא להיות עקביים בדרך הברורה עבור פרימיטיבים. לדוגמה, אם הקוד הבינארי של C++ מחשב חתימה עם public_key_sign->Sign(data), הקריאה התואמת ב-Java publicKeyVerify.verify(signature, data) צפויה להצליח.

עם זאת, יש כאן כמה נקודות שצריך לשים לב אליהן. לדוגמה, סוג ההחזרה של aead.Encrypt ב-Java הוא byte[]. לפי סעיף 10.7 של מפרט Java Language Specification (JLS), אורך מערך הוא מסוג int, ולכל סעיף JLS 4.2.1 יכול להיות עד 2147483647. לכן, הצפנה של מערך באורך 2147483647 נכשלת ב-Java: להצפנה יש תקורה מסוימת, כלומר הפלט ארוך מדי. עם זאת, בשפות אחרות הצפנה מורשית להצליח בקלט כזה.

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

יש יוצא מן הכלל שיכול להיות שפעולות מסוימות ייכשלו בנסיבות חריגות.

עקביות בתהליך היצירה

יצירה של פרימיטיבים לא תמיד מצליחה בכל קבוצות המפתחות. לדוגמה, Tink לא מאפשר למשתמשים ליצור AesSivKey אם חומר המפתח הוא באורך 128 ביט.

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

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


  1. במסמך הזה אנחנו משתמשים במונח Keyset כדי לציין את האובייקט שנקרא KeysetHandle ברוב השפות.