Authentication

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

  • אחסון מפתחות קריפטוגרפיים וספק שירותים. מאחסן מפתחות קריפטוגרפיים ומספק תוכניות קריפטוגרפיות רגילות מעל המפתחות האלה. Android תומך ב-Keystore שמבוסס על חומרה וב-Keymaster לשירותים קריפטוגרפיים, כולל הצפנה שמבוססת על חומרה לאחסון מפתחות, שעשויה לכלול Trusted Execution Environment‏ (TEE) או Secure Element‏ (SE), כמו Strongbox.
  • מאמתי משתמשים. אימות נוכחות המשתמש ו/או אימות מוצלח. Android תומך ב-Gatekeeper לאימות באמצעות קוד אימות, קו ביטול נעילה או סיסמה, וב-Fingerprint לאימות באמצעות טביעת אצבע. במכשירים עם Android מגרסה 9 ואילך אפשר להשתמש ב-BiometricPrompt כנקודת שילוב אחת לזיהוי טביעת אצבע ולזיהוי ביומטרי נוסף. הרכיבים האלה מעבירים את מצב האימות שלהם לשירות מאגר המפתחות דרך ערוץ מאומת. (גם מערכת Android Keystore ברמת המסגרת נתמכת על ידי שירות ה-Keystore).

הרכיבים Gatekeeper,‏ Fingerprint ו-Biometric פועלים עם Keystore ורכיבים אחרים כדי לתמוך בשימוש באסימוני אימות (AuthTokens) שמגובים בחומרה.

הרשמה

בהפעלה הראשונה של המכשיר אחרי איפוס להגדרות המקוריות, כל מאמתי הזהויות מוכנים לקבל מהמשתמש הרשמות של פרטי כניסה. בשלב הראשון, המשתמש צריך להירשם ל-Gatekeeper באמצעות קוד אימות, קו ביטול נעילה או סיסמה. ההרשמה הראשונית יוצרת מזהה מאובטח (SID) של משתמש באורך 64 ביט שנוצר באופן אקראי, ומשמש כמזהה של המשתמש וכאסימון קישור לחומר הקריפטוגרפי של המשתמש. ה-SID של המשתמש הזה קשור באופן קריפטוגרפי לסיסמה של המשתמש. אימותים מוצלחים ב-Gatekeeper יוצרים AuthTokens שמכילים את ה-SID של המשתמש עבור הסיסמה הזו.

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

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

אימות

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

תהליך האימות
איור 1. תהליך האימות
  1. משתמש מספק שיטת אימות, והשירות המשויך שולח בקשה לדימון המשויך.
    • אם מדובר בקוד אימות, בקו ביטול נעילה או בסיסמה, LockSettingsService שולחת בקשה ל-gatekeeperd.
    • תהליכי האימות מבוססי הביומטריה תלויים בגרסה של Android. במכשירים עם Android מגרסה 8.x ואילך, FingerprintService שולח בקשה ל-fingerprintd. במכשירים עם Android מגרסה 9 ואילך, BiometricPrompt שולח בקשה לדיימון הביומטרי המתאים (לדוגמה, fingerprintd לזיהוי טביעות אצבע או faced לזיהוי פנים) באמצעות הכיתה המתאימה של BiometricManager, כמו FingerprintManager או FaceManager. ללא קשר לגרסה, האימות הביומטרי מתבצע באופן אסינכרוני אחרי שליחת הבקשה.
  2. הדימון שולח נתונים לצד השני, שיוצר AuthToken:
    • באימות באמצעות קוד אימות, קו ביטול נעילה או סיסמה, gatekeeperd שולח את הגיבוב של קוד האימות, קו ביטול הנעילה או הסיסמה אל Gatekeeper ב-TEE. אם האימות ב-TEE מצליח, השומר (Gatekeeper) ב-TEE שולח אסימון AuthToken שמכיל את ה-SID התואם של המשתמש (חתום באמצעות מפתח ה-HMAC של AuthToken) למקבילו במערכת ההפעלה של Android.
    • באימות באמצעות טביעת אצבע, fingerprintd מקשיב לאירועי טביעת אצבע ושולח את הנתונים ל-Fingerprint ב-TEE. אם האימות ב-TEE מצליח, Fingerprint ב-TEE שולח AuthToken (חתום במפתח ה-HMAC של AuthToken) למקבילו ב-Android OS.
    • באימות ביומטרי אחר, הדימון הביומטרי המתאים ממתין לאירוע הביומטרי ושולח אותו לרכיב ה-TEE הביומטרי המתאים.
  3. הדימון מקבל אסימון AuthToken חתום ומעביר אותו לשירות של מאגר המפתחות באמצעות תוסף לממשק Binder של שירות מאגר המפתחות. (gatekeeperd גם מודיע לשירות מאגר המפתחות כשהמכשיר ננעל מחדש וכשהסיסמה של המכשיר משתנה).
  4. שירות מאגר המפתחות מעביר את AuthTokens ל-Keymaster ומאמת אותם באמצעות המפתח ששותף עם Gatekeeper ורכיב TEE ביומטרי נתמך. ‏Keymaster סומך על חותמת הזמן באסימון כזמן האימות האחרון, ומבוסס על חותמת הזמן כדי להחליט אם לשחרר את המפתח (כדי לאפשר לאפליקציה להשתמש במפתח).

הפורמט של AuthToken

כדי להבטיח שיתוף של האסימון ותאימות בין שפות ורכיבים, הפורמט של AuthToken מתואר בקטע hw_auth_token.h. הפורמט הוא פרוטוקול פשוט לסריאליזציה עם שדות בגודל קבוע.

שדה סוג חובה תיאור
גרסת AuthToken בייט אחד כן תג קבוצה לכל השדות הבאים.
האתגר מספר שלם ללא סימן (unsigned integer) של ‎64 סיביות לא מספר שלם אקראי למניעת התקפות שליחה מחדש. בדרך כלל המזהה של פעולת הצפנה מבקשת. נמצא כרגע בשימוש בהרשאות של טביעת אצבע עסקית. אם הוא קיים, AuthToken תקף רק לפעולות קריפטוגרפיות שמכילות את אותו אתגר.
User SID מספר שלם ללא סימן (unsigned integer) של ‎64 סיביות כן מזהה משתמש שאינו חוזר על עצמו ומקושר באופן קריפטוגרפי לכל המפתחות שמשויכים לאימות המכשיר. פרטים נוספים זמינים במאמר Gatekeeper.
מזהה מאמת (ASID) מספר שלם ללא סימן (unsigned integer) של 64 סיביות בסדר רשת לא מזהה המשמש לקישור למדיניות ספציפית של מאמת. לכל מאמת יש ערך ASID משלו, שאותו הוא יכול לשנות בהתאם לדרישות שלו.
סוג מאמת החשבונות מספר שלם ללא סימן באורך 32 ביט בסדר רשת כן
  • 0x00 הוא שומר הסף.
  • 0x01 הוא טביעת אצבע.
חותמת זמן מספר שלם ללא סימן (unsigned integer) של 64 סיביות בסדר רשת כן הזמן (באלפיות שנייה) מאז האתחול האחרון של המערכת.
AuthToken HMAC‏ (SHA-256) blob של 256 ביט כן MAC של SHA-256 עם מפתח לכל השדות, מלבד השדה HMAC.

תהליך האתחול של המכשיר

בכל הפעלה של מכשיר, צריך ליצור את מפתח ה-HMAC של AuthToken ולשתף אותו עם כל הרכיבים של TEE (‏Gatekeeper,‏ Keymaster ו-trustlets ביומטריים נתמכים). לכן, כדי להגן מפני התקפות שחזור, צריך ליצור את מפתח ה-HMAC באופן אקראי בכל פעם שהמכשיר מופעל מחדש.

הפרוטוקול לשיתוף מפתח ה-HMAC הזה עם כל הרכיבים הוא תכונת הטמעה שתלויה בפלטפורמה. אסור להפוך את המפתח לזמין מחוץ ל-TEE. אם למערכת ההפעלה של TEE אין מנגנון פנימי של תקשורת בין תהליכים (IPC) והיא צריכה להעביר את הנתונים דרך מערכת ההפעלה הלא מהימנה, ההעברה צריכה להתבצע באמצעות פרוטוקול מאובטח של החלפת מפתחות.

מערכת ההפעלה Trusty, שפועלת לצד Android, היא דוגמה לסביבת TEE, אבל אפשר להשתמש בסביבות TEE אחרות במקום זאת. ‏Trusty משתמש במערכת IPC פנימית כדי לתקשר ישירות בין Keymaster ל-Gatekeeper או ל-trustlet הביומטרי המתאים. מפתח ה-HMAC נשמר רק ב-Keymaster. Fingerprint ו-Gatekeeper מבקשים את המפתח מ-Keymaster בכל שימוש, ולא שומרים את הערך או שומרים אותו במטמון.

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