בדף הזה מוסבר איך לוודא שקובץ ה-APK או ה-APEX שהותקן במכשיר Android תואם לטענות שמופיעות במודל של בעל הזכויות. התהליך כולל שליפה של ה-APK מהמכשיר וביצוע הוכחה להכללת היומן בארטיפקט שחולץ.
תהליך האימות
יומן שקיפות מיושם באמצעות עץ מרקל שמורכב מגיבובים. צומת עלה מכיל נתונים, וצומת הורה מכיל את הגיבוב של הצמתים הצאצאים שלו.
יש שני חישובים בסיסיים שמאמתים את המאפיין של יומני שקיפות שמוכיח שאין בהם שינויים לא מורשים: הוכחת הכללה והוכחת עקביות. הוכחת ההכללה מאשרת שהיומן כולל רשומה של גרסה ספציפית של APK. רשומת היומן הזו מכילה גיבוב, שהוא תקציר SHA256 של קובץ ה-APK שמותקן במכשיר. הוכחת העקביות מבטיחה שכאשר נוספים ערכים חדשים, נקודת הבדיקה החדשה נשארת עקבית מבחינה קריפטוגרפית עם גרסאות קודמות של העץ (או שהעץ לא עבר שינוי לא מורשה). במדריך הזה אנחנו מתמקדים בתהליך של חישוב הוכחת ההכללה, תוך הסתמכות על עדים לביצוע הוכחת עקביות באופן רציף מול נקודות הבדיקה האחרונות.
כדי לאמת קובץ APK מכוסה, מבצעים הוכחת הכללה מול נקודת ביקורת שנצפתה. חשוב לשים לב שאנחנו מתכננים לשלב את היומן הזה עם רשת עדים ציבורית באמצעות פרוטוקול עדים סטנדרטי. השילוב הזה יספק נקודות ביקורת מאומתות, שיבטיחו את העקביות של היומן.
כדי לוודא שאפליקציות Google במכשיר שלכם תואמות לטענות שמופיעות במודל של התובע, פועלים לפי השלבים הבאים.
הוכחת הכללה
כדי לוודא שקובץ APK שנתמך במכשיר מופיע ביומן, אפשר לחלץ את קובץ ה-APK, לחשב את הגיבוב שלו ולהשתמש בהוכחת הכללה כדי לבדוק אם הגיבוב הזה קיים בנקודת הבדיקה שפורסמה. הוכחת הכללה מוצלחת מספקת ביטחון מפני הסיכונים שמתוארים במודל האיומים, ומאשרת שהאפליקציה היא אפליקציית Google לגיטימית.
איך מאמתים הכללה של קובץ APK ביומן
אפשר לאמת כל אפליקציית Google שטוענת שהיא אפליקציית צד ראשון באמצעות היומן הזה.
דרישות מוקדמות לאימות
לפני שמאמתים קובץ APK שחולץ, צריך להתקין במחשב את הכלים הבאים:
ממשק הגישור של Android (ADB)
ADB הוא כלי שמתקשר עם מכשיר Android, והוא זמין באתר Android SDK Platform Tools.
AAPT2
AAPT2 (Android Asset Packaging Tool) הוא כלי לבנייה שמשמש לקומפילציה ולאריזה של משאבים באפליקציית Android.
הוא זמין ככלי עצמאי ב-Android SDK Build Tools מגרסה 26.0.2 ומעלה.
Golang
כלי האימות כתוב בשפת Go. כדי לבנות אותו, צריך להתקין את Go 1.17 ואילך מהאתר של Go.
כלי לאימות הוכחת הכללה
אנחנו מפרסמים מודול Go בשם verifier במאגר GitHub של android-binary-transparency.
הכלי הזה שולח שאילתה ליומן השקיפות של חבילות APK של צד ראשון של Google כדי לבדוק אם חבילה כלולה בו.
כדי להשתמש בכלי הזה, קודם משכפלים את המאגר למחשב המקומי:
git clone https://github.com/android/android-binary-transparency
קוד המקור של הכלי לאימות נמצא במאגר android-binary-transparency.
יצירת מטען ייעודי (Payload) לאימות
כדי לאמת את ה-APK שחולץ, צריך ליצור מטען ייעודי (payload) של יומן באמצעות מידע שמקורו ב-APK עצמו.
לפני שמתחילים, צריך להפעיל ניפוי באגים ב-USB במכשיר כדי לאפשר חיבורים ל-adb.
לאחר מכן, מאתרים את קובץ ה-APK שהותקן במכשיר. במדריך הזה נעשה שימוש ב-APK של Google Play Services (com.google.android.gms) כדוגמה מעשית.
adb shell pm path com.google.android.gms
הפלט אמור להיראות כך:
computer:~$ adb shell pm path com.google.android.gms
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/base.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_CronetDynamite_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_DynamiteLoader_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_DynamiteModulesA_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_DynamiteModulesC_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_GoogleCertificates_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_MapsDynamite_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_MeasurementDynamite_installtime.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_config.en.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_config.xxhdpi.apk
package:/data/app/~~oI3N-m7I3VNMk5eKUCscQg==/com.google.android.gms-O79jYXgqkqKaQ9IzJ5zqfA==/split_maps_core_dynamite_ondemand.apk
הפלט הזה מציין שחבילת APK בסיסית אחת וכמה חבילות APK מפוצלות מותקנות עבור com.google.android.gms במכשיר.
המספר המדויק של קובצי ה-APK המפוצלים משתנה בהתאם לתצורת המכשיר.
לכל APK מפוצל יש את אותו שם חבילה ואותו קוד גרסה כמו ל-APK הבסיסי.
מורידים את קובצי ה-APK שמופיעים ברשימה ממכשיר Android למחשב באמצעות הפקודה הבאה (שימו לב שנתיבי הקבצים בפועל עשויים להיות שונים):
mkdir -p /tmp/testdir/gms && cd /tmp/testdir/gms && \
adb shell pm path com.google.android.gms | cut -d':' -f2 | tr -d '\r' | xargs -n1 adb pull
כדי לוודא את שם החבילה והגרסה של קובצי ה-APK שהורדתם, צריך לבדוק את המניפסט שלהם (AndroidManifest.xml).
קובץ המניפסט בתוך ה-APK הוא בפורמט בינארי, לכן צריך להשתמש בכלי aapt2 (שמותקן במהלך השלב של הדרישות המוקדמות) כדי לחלץ את המידע ולקרוא אותו ישירות מה-APK:
computer:/tmp/testdir/gms$ aapt2 dump badging ./base.apk
package: name='com.google.android.gms' versionCode='260834035' versionName='26.08.34 (260400-876566425)' platformBuildVersionName='Baklava' platformBuildVersionCode='36' compileSdkVersion='36' compileSdkVersionCodename='Baklava'
minSdkVersion:'35'
targetSdkVersion:'36'
...
כדי לקבל את המידע הרלוונטי, צריך לחזור על השלב הזה עד שמתקבלים נתונים על כל חבילות ה-APK המפוצלות שמותקנות במכשיר.
בפלט אפשר לראות ששם החבילה של ה-APK הוא com.google.android.gms ומספר הגרסה שלו (versionCode) הוא 260834035.
לאחר מכן, מחשבים את הגיבוב הקריפטוגרפי של כל קובץ APK:
computer:/tmp/testdir/gms$ sha256sum *.apk
66aa2d7b9752cdd61065b55c8e16739d8367fa18a0f1c8c84122369f86958f1a base.apk
c20754aee886cc55a9de91ee15c623c59d94ad22b7e435a1a48afc43cf1a106c split_config.en.apk
68c09b63a1262e0d34020c139bc77deff3c32bd2b01177abac64790a62fb3be6 split_config.xxhdpi.apk
cd746820c27babd855fa5daea6fabcdf7b44abf3060bc547adc4219212410af0 split_CronetDynamite_installtime.apk
512ee48b60fdb0787a17f84a7dc448fdbf885b2b86a9cb50525d4c22d561b0f1 split_DynamiteLoader_installtime.apk
9e0c74bdc75c50c80d4e2e580a7eda6b8391423ab1161645f41ec6cadc07d678 split_DynamiteModulesA_installtime.apk
955780ac01f59b98bd9be12968f3824ad71b762620f7bf223c569c1a6ab7056c split_DynamiteModulesC_installtime.apk
34c4a2e32d31554d55fc1519e2cfc3ed5027a090fb29b54cfc99f42d1da43bc5 split_GoogleCertificates_installtime.apk
475e18dde92472cde9d8300c082b6dc269613db03398bcd9d1987dff3e68f7b5 split_maps_core_dynamite_ondemand.apk
f83faf40f08bc13f4879302e01c08c863ca2304b4b4e7c9eaf8cd1e869bb6573 split_MapsDynamite_installtime.apk
ec6d854ddda6cd1ba2ba7af2d9fdf4f28c5c78be8713c64521c785429296738c split_MeasurementDynamite_installtime.apk
עכשיו יש לכם את כל המידע שנדרש כדי ליצור מטען ייעודי (payload) של יומן, בפורמט שמתואר בקטע 'תוכן היומן'. אם בוחרים ערך גיבוב אחד מהתוצאות כדוגמה (צריך לאמת את הגיבוב של כל קובץ APK מפוצל), מטען הנתונים של היומן נראה כך:
66aa2d7b9752cdd61065b55c8e16739d8367fa18a0f1c8c84122369f86958f1a
SHA256(APK)
com.google.android.gms
260834035
חשוב לוודא שמוסיפים תו מעבר לשורה בסוף הקובץ. שומרים את התוכן הזה בקובץ, כמו payload.txt, כדי להשתמש בו בכלי verifier בהמשך.
אימות הכללה של חבילה (הוכחת הכללה)
אחרי שיוצרים את מטען הנתונים, אפשר לבדוק אם החבילה נכללת ביומן השקיפות. יוצרים את כלי הוכחת ההכללה ממאגר android-binary-transparency ששיבטתם קודם:
go build cmd/verifier/verifier.go
התוצאה תהיה קובץ הפעלה בשם verifier בספרייה הזו.
מריצים את הכלי לאימות, מציינים את הנתיב למטען הייעודי (payload) ואת סוג היומן:
computer:android-binary-transparency$ PAYLOAD_PATH=PATH_TO_PAYLOAD_DIR/payload.txt
computer:android-binary-transparency$ ./verifier --payload_path=${PAYLOAD_PATH} --log_type=google_1p_apk
המאמת משתמש בנקודת הבדיקה ובתוכן היומן (מתוך ספריית האריחים) כדי לבדוק אם מטען ה-APK נמצא ביומן השקיפות, וכך לוודא שהוא פורסם על ידי Google.
הפלט של הפקודה מועבר אל stderr:
-
OK. inclusion check success!אם החבילה כלולה ביומן. FAILUREאם הוא לא מוגדר.
אימות אוטומטי של כל החבילות במכשיר
בהתחשב במספר אפליקציות Google שעשויות להיות מותקנות מראש במכשיר שלכם, יכול להיות שיהיה מייגע למנות כל אפליקציה ולבצע הוכחות הכללה בנפרד.
אנחנו מספקים כלי אוטומטי נוסף בשם Uraniborg שיכול לזהות ולמדוד את כל החבילות שמותקנות כרגע במכשיר.
הפלט של הכלי מוזן ישירות לתוך הכלי verifier, וכך אתם יכולים לגלות ולאמת את השקיפות של כל האפליקציות במכשיר שלכם בפעולה אחת.
כדי להשתמש בתהליך העבודה האוטומטי הזה, צריך לוודא שמכשיר Android מחובר למחשב באמצעות ADB. קוד המקור Uraniborg כלול גם במאגר android-binary-transparency.
מריצים את הסקריפט automate_observation.py שנמצא בספרייה scripts/python:
python3 automate_observation.py --pull-all-apks --perform_inclusion_proof_check --verifier_path <path_to_verifier_executable>
בסיום הפעלת הסקריפט, הפלט אמור להיראות כך:
INFO:automate_observation.py:main(858): SUCCESS! Hubble was successfully deployed and executed on connected device ABCDEFGHN01234.
INFO:automate_observation.py:main(860): Hubble output files can be found at: /Users/user/home/src/android-binary-transparency/uraniborg/scripts/python/results/google/lynx/lynx:16/BP4A.260105.004.E1/14587043:user/release-keys/001
עוברים לספריית הפלט שמצוינת בסקריפט.
בתוך התיקייה, מאתרים את הקובץ בשם packages_with_inclusion_proof_signal.txt.
בקובץ הזה מפורטת כל חבילה שהותקנה לצד השדה inclusion_proof_verified שמוגדר לערך true או false.
הערך true מציין שהחבילה אומתה באופן קריפטוגרפי מול יומן השקיפות, ושהיא עומדת בדרישות של היומן.