בדף הזה מפורטות שיטות שונות לוודא שקובץ ה-APK שמותקן במכשיר Android תואם לטענה שמופיעה במודל של בעל הזכויות. התהליך כולל שליפה של ה-APK הרלוונטי מהמכשיר, בדיקה של תקינות הקוד וביצוע הוכחה של הכללה ביומן בפריט המידע שחולץ.
תהליך האימות
יומן שקיפות מיושם באמצעות עץ מרקל שמורכב מגיבובים. צומת עלה מכיל נתונים, וצומת הורה מכיל את הגיבוב של הצמתים הצאצאים שלו.
בעצם, מתבצעים שני חישובים בעץ מרקל כדי לאמת את המאפיין של יומני שקיפות שמוכיח שהם לא שונו: הוכחת הכללה והוכחת עקביות. האפשרות הראשונה מוכיחה שהיומן כולל רשומה שתואמת לגרסת APK מסוימת. רשומת היומן כוללת גיבוב (hash), שהוא תקציר SHA256 של טוקן חתימת הקוד בפורמט JSON Web Token (JWT), שאפשר לקבל מקובצי APK תואמים. האחרון מוכיח שכאשר מוסיפים רשומות חדשות לעץ, נקודת הבדיקה החדשה עקבית (מבחינה קריפטוגרפית) עם הגרסה הקודמת של העץ.
כדי לאמת קובץ APK מכוסה, מבצעים בדיקת הוכחת הכללה על סמך נקודת ביקורת שנצפתה. שימו לב שאנחנו מתכננים לשלב את היומן הזה עם רשת עדים ציבורית באמצעות פרוטוקול עדים סטנדרטי. כך תקבלו נקודת ביקורת שבה נכח עד, שמבטיחה את העקביות של היומן.
אם אתם רוצים לוודא שקובץ ה-APK ששמור במכשיר שלכם תואם לטענה שמופיעה במודל של בעל התלונה, תוכלו לעיין בתיאור שבהמשך.
הוכחת הכללה
משתמש Android יכול לבדוק אם קובץ APK מכוסה במכשיר שלו נמצא ביומן. לשם כך, הוא צריך קודם לחלץ את קובץ ה-APK ואת המטא-נתונים הרלוונטיים שלו, ואז להשוות את הגיבוב הבסיסי שחושב מחדש לגיבוב הבסיסי שמופיע בנקודת הבדיקה שפורסמה. אם הם זהים, משתמש Android יכול להיות בטוח שחלק מההגנות שמתוארות במודל האיומים יופעלו.
איך מאמתים הכללה של קובץ APK ביומן
כמו שצוין קודם, רשימת קובצי ה-APK שכלולים כרגע בתוכנית מופיעה בדף הסקירה הכללית.
דרישות מוקדמות לאימות
לפני שתמשיכו לאימות קובץ ה-APK שזה עתה חילצתם מהמכשיר שלכם בהתאם לתביעה שלנו, תצטרכו להתקין את הכלים הבאים במחשב שמחובר לרשת.
ממשק הגישור של Android (ADB)
ADB הוא כלי שמתקשר עם מכשיר Android, והוא זמין באתר Android SDK Platform Tools.
AAPT2
AAPT2 (Android Asset Packaging Tool) הוא כלי לבנייה שמשמש להידור ולאריזה של משאבי אפליקציית Android. אפשר למצוא אותו ככלי עצמאי ב-Android SDK Build Tools מגרסה 26.0.2 ואילך.
bundletool
bundletool הוא כלי שמשמש ליצירת קובץ Android App Bundle (AAB). אפשר להשתמש בו גם כדי להמיר קובץ AAB לקובצי APK שאפשר להתקין במכשירים.
אפשר להוריד אותו מ-GitHub.
כלי לאימות הוכחת ההכללה
זהו מודול Go שפרסמנו במאגר Git בפרויקט הקוד הפתוח של Android (AOSP) בשם avb.
הכלי יכול לשלוח שאילתות ליומן השקיפות של חבילות APK בשירותי המערכת של Google, ולציין אם חבילה מסוימת נכללת ביומן.
דוגמה לשימוש בשיטה הזו מופיעה בקטע בהמשך.
כדי להוריד את הכלי הזה, קודם צריך לשכפל את מאגר avb.
computer:~$ git clone https://android.googlesource.com/platform/external/avb
קוד המקור של הכלי לאימות נמצא ב-tools/transparency/verify
במאגר avb.
יצירת מטען ייעודי (Payload) לאימות
כדי לוודא שקובץ ה-APK שחולץ מהמכשיר תואם לטענות שלנו, צריך ליצור מטען ייעודי (payload) של יומן ממידע שנגזר מקובץ ה-APK.
לפני שמתחילים, צריך לוודא שאפשר להשתמש ב-adb במכשיר. לשם כך, מפעילים את ניפוי הבאגים של adb במכשיר.
לאחר מכן, מאתרים את המקום שבו קובץ ה-APK מותקן במכשיר. לצורך המדריך הזה, נשתמש בקובץ ה-APK של Android System Key Verifier (com.google.android.contactkeys) כדוגמה.
computer:~$ adb shell pm list packages -f | grep contactkeys
package:/data/app/~~i5WYSO4PuAAv798-eHdM7A==/com.google.android.contactkeys-PQCKjnn7xDqjeVhcUDibBA==/base.apk=com.google.android.contactkeys
אם קובץ ה-APK של הכלי לאימות מפתחות של מערכת Android מותקן במכשיר, הפקודה שלמעלה תחזיר נתיב שמציין את המקום שבו הוא מותקן במכשיר. אחרת, לא יוצג פלט.
לאחר מכן, מורידים את ה-APK ממכשיר Android למחשב שבו עובדים באמצעות הפקודה הבאה (שימו לב שהמיקום בפועל ושם קובץ ה-APK במכשיר עשויים להיות שונים):
computer:~$ mkdir -p /tmp/testdir && cd /tmp/testdir
computer:/tmp/testdir$ adb pull /data/app/~~i5WYSO4PuAAv798-eHdM7A==/com.google.android.contactkeys-PQCKjnn7xDqjeVhcUDibBA==/base.apk ./contactkeys_candidate.apk
כדי לקבל את שם החבילה של ה-APK שהורדתם ולכן גם לאמת אותו, תצטרכו קודם לפתוח את ה-APK, כי בסופו של דבר מדובר בסוג מיוחד של קובץ ZIP.
computer:/tmp/testdir$ mkdir extracted && unzip contactkeys_candidate.apk -d extracted/
בשלב הזה מתבצעת פריקה של כל הקבצים שמרכיבים את קובץ ה-APK. שם החבילה והגרסה מופיעים במניפסט של ה-APK, שבדרך כלל נמצא בקובץ בשם AndroidManifest.xml.
עם זאת, קובץ המניפסט שמתקבל הוא בינארי, ולכן לא קריא לאנשים.
כדי להמיר את ה-XML הבינארי לפורמט קריא, אנחנו משתמשים בכלי aapt2 שהתקנו קודם (כפי שנדרש בסעיף הדרישות המוקדמות).
computer:/tmp/testdir$ aapt2 dump badging ./contactkeys_candidate.apk
package: name='com.google.android.contactkeys' versionCode='7805' versionName='1.219.791156583' platformBuildVersionName='Baklava' platformBuildVersionCode='36' compileSdkVersion='36' compileSdkVersionCodename='Baklava'
מהפלט שלמעלה, אפשר לראות ששם החבילה של ה-APK הזה הוא com.google.android.contactkeys ומספר הגרסה (versionCode) הוא 1413.
עכשיו נחפש את החתימה של שקיפות הקוד ב-APK. זה צריך להיות קובץ בשם code_transparency_signed.jwt שנמצא בתיקייה META-INF בין הקבצים האחרים שחולצו מקובץ ה-APK.
computer:/tmp/testdir$ sha256sum extracted/META-INF/code_transparency_signed.jwt
1779a2aee029112c2c9bfc9390b9678f3e5f4595b39705e8528dd522e8042f11 code_transparency_signed.jwt
עם מחרוזת הגיבוב הזו, יש לנו עכשיו את כל המידע שדרוש כדי להרכיב מטען ייעודי למטרה מסוימת של יומן, בהתאם לפורמט שמתואר בקטע 'תוכן היומן'. בדוגמה הזו, מטען ייעודי (payload) של יומן תואם צריך להיראות כך:
1779a2aee029112c2c9bfc9390b9678f3e5f4595b39705e8528dd522e8042f11
SHA256(Signed Code Transparency JWT)
com.google.android.contactkeys
1143
שימו לב גם לתו של השורה החדשה אחרי גרסת החבילה.
אפשר לשמור את התוכן בקובץ, למשל payload.txt. המידע הזה יהיה שימושי בהמשך כשנבדוק את הכללת ההוכחה.
אימות האותנטיות של חתימת קוד ה-APK
עכשיו צריך לאמת את האותנטיות של אסימון חתימת הקוד שמוטמע ב-APK. לשם כך, אנחנו משתמשים ב-bundletool ובמפתח הציבורי של זוג המפתחות ששימש לחתימה על הנתונים מלכתחילה. הם מתפרסמים בכל קטע של קובצי ה-APK המתאימים. בהנחה ששמרתם את אישור המפתח הציבורי (למשל, עבור Android System Key Verifier) בקובץ בשם signing_cert_pubkey.pem, פועלים לפי ההוראות שבהמשך כדי לבצע אימות של חתימת הקוד.
קודם צריך ליצור ארכיון zip ולהוסיף אליו את קובץ ה-APK של המועמד.
computer:/tmp/testdir$ zip -u test.zip contactkeys_candidate.apk
zip warning: test.zip not found or empty
adding: contactkeys_candidate.apk (deflated 58%)
computer:/tmp/testdir$ file test.zip
test.zip: Zip archive data, at least v2.0 to extract, compression method=deflate
עכשיו אפשר להשתמש בפקודה bundletool של check-transparency כדי לוודא שחתימת הקוד שמוטמעת בקובץ ה-APK של המועמד זהה לחתימה שפורסמה.
computer:/tmp/testdir$ java -jar BUNDLETOOL_INSTALL_PATH/bundletool-all-version.jar check-transparency \
--mode=apk \
--apk-zip=test.zip \
--transparency-key-certificate=signing_cert_pubkey.pem
APK signature is valid. SHA-256 fingerprint of the apk signing key certificate (must be compared with the developer's public key manually): D9 E1 73 5B 2A 39 51 27 3A 87 35 B7 66 9E F1 9E F5 3A F1 C1 27 5C BA 31 39 3C 18 40 8B 03 79 D0
Code transparency signature verified for the provided code transparency key certificate.
Code transparency verified: code related file contents match the code transparency file.
צריך לוודא שהפלט של הפקודה שלמעלה מציין שגם החתימה של שקיפות הקוד וגם שקיפות הקוד אומתו.
אם הם לא זהים, למשל אם מוצג פלט כמו
Code transparency verification failed because the provided public key
certificate does not match the transparency file, המשמעות היא ששלמות הקוד של ה-APK המדובר עלולה להיות
בסיכון, ולא מומלץ לסמוך על ה-APK.
חשוב לוודא שאתם מאמתים אותם מול אישור המפתח הציבורי הנכון.
אחרת, אם כל שאר הבדיקות תקינות, המשמעות היא שהאותנטיות של חתימת הקוד אומתה עבור קובץ ה-APK שאתם מאמתים.
אימות הכללת החבילה (הוכחת הכללה)
עכשיו אפשר לבדוק אם החבילה הרלוונטית נכללה ביומן השקיפות, באמצעות מטען הייעודי (payload) שיצרתם קודם.
כלי להוכחת הכללה פורסם בavb מאגר בפרויקט הקוד הפתוח של Android. כדי להפעיל אותו:
computer:external/avb/tools/transparency/verify$ PAYLOAD_PATH=PATH_TO_PAYLOAD_DIR/payload.txt
computer:external/avb/tools/transparency/verify$ go build cmd/verifier/verifier.go
computer:external/avb/tools/transparency/verify$ ./verifier --payload_path=${PAYLOAD_PATH} --log_type=google_system_apk
המאמת משתמש בנקודת הבדיקה המתאימה ובתוכן היומן (שנמצא בספריית האריחים) כדי לבדוק שמטען ה-APK נמצא ביומן השקיפות, וכך לוודא שהוא אכן פורסם על ידי Google.
הפלט של הפקודה נכתב אל stdout:
-
OK. inclusion check success!אם הקוד של החבילה כלול ביומן, FAILUREאם לא.