אבטחה

איך הכספת בנויה, ומה תגלה פרצה.

עודכן לאחרונה ב-21 בספטמבר 2026 · AssuredAuth, על ידי CircleRoll LLC

זהו התיאור הציבורי כיצד AssuredAuth מגן על הסודות הדו-גורמיים, הסיסמאות והכרטיסים שאתם שומרים בו. הוא כתוב כך שקורא בעל חשיבה ביטחונית יוכל לבדוק כל טענה כנגד האפליקציה וכנגד וקטורי הבדיקה שפורסמו (זמינים לכל סוקר לפי בקשה בכתובת hello@assuredauth.com). הוא אומר את מה שנכון ולא יותר: שום דבר כאן לא טוען שהוא מעבר לתקיפה, ושום דבר לא מובטח באחוזים.

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

דווח על בעיה: hello@assuredauth.com. ראה "דיווח על חולשה" בסוף.

1. מה מוצפן, עם מה

נתוניםבטלפוןמפתח
סודות דו-גורמיים (זרעי TOTP/HOTP/Steam) בטלפוןחנות מגובה על ידי Keystore (iOS) / אנדרואיד מפתחהמפתח הקשור לחומרה של הפלטפורמה; שורת מסד הנתונים מכילה רק הפניה (secretRef), לעולם לא את ה-seed.
סיסמאות (ערך הסיסמה, הערות) בטלפוןשורה אטומה: AES-256-GCM, ערך אקראי של 96 סיביות ללא ערך (nonce) לכל ערך מפתחמפתח נתונים אקראי של 256 סיביות, אשר עצמו עטוף במפתח החומרה בסעיף 2
כרטיסים (מספר, תוקף, שם על הכרטיס, קוד אימות) בטלפוןאותו חותם כמו סיסמאות; קוד ה-CVC הוא אופציונלי ונשמר רק אם תזין אותו מפתחאותו מפתח נתונים
מטא-נתונים (שמות שירותים, שמות משתמש, סמלים, סדר מיון) בטלפוןמסד הנתונים של האפליקציה (SwiftData / Room) מפתחמוגן על ידי הצפנת הקבצים של מערכת ההפעלה; מטופל כלא סודי
קובץ גיבוי (.authbackup) בטלפוןאיפה שלא תשימו את זה: קבצים, iCloud Drive, Google Drive appDataFolder, גיליון שיתוף מפתחמפתח שנגזר מביטוי הסיסמה שלך (§3). אפל וגוגל מקבלות את הקובץ האטום ושום דבר אחר
אפליקציה נלווית ל-Watch / Wear בטלפוןמחזיק המפתחות של השעון עצמו / EncryptedSharedPreferences מפתחמפתחות פלטפורמת השעון; מועברים דרך ערוץ המכשיר המשויך של הפלטפורמה
תעבורת תוספים למחשב שולחני (קודים חד פעמיים לפי בקשה) בטלפוןלא מאוחסן; מועבר כמעטפות מוצפנות מקצה לקצה מפתחזוג מפתחות X25519 לכל זיווג, מפתח פרטי במחזיק המפתחות / מאגר המפתחות; הממסר רואה רק טקסט מוצפן

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

2. היכן נמצאים המפתחות, בכל פלטפורמה

iOS. מפתח הנתונים עטוף במפתח שנוצר בתוך ה-Secure Enclave (kSecAttrTokenIDSecureEnclave) עם בקרת גישה .privateKeyUsage + .userPresence, accessibility …ThisDeviceOnly, בקבוצת הגישה המשותפת של Keychain של האפליקציה, כך שהרחבת AutoFill יכולה להשתמש באותו מפתח. לא ניתן לקרוא את המפתח הפרטי מה-Enclave על ידי האפליקציה, על ידי גיבוי או על ידי ניפוי שגיאות; ה-Enclave מסכים להשתמש בו רק לאחר שהמשתמש נוכח (Face ID, Touch ID או קוד הגישה של המכשיר). ThisDeviceOnly פירושו שגיבוי iCloud או iTunes של הטלפון אינו נושא את המפתח; טלפון משוחזר מתחיל בכספת ריקה ומבקש את קובץ הגיבוי והסיסמה שלך. טלפון ללא קוד גישה אינו יכול לגשת למפתח .userPresence (ה-Enclave מסרב ליצור אחד כזה), והסימולטור נוקט באותו מסלול מעצם עיצובו (הנחיית הנוכחות שלו היא התראה שאף בדיקה לא יכולה לענות עליה): שם מפתח הנתונים הוא פריט מחזיק מפתחות רגיל של המכשיר בלבד - עדיין מחוץ לכל גיבוי, עדיין בלתי קריא בזמן שהטלפון נעול, אך ללא הנחיה שנייה - ומסך האבטחה אומר בדיוק את זה ומציע להגדיר קוד גישה.

Android. מפתח הנתונים עטוף במפתח AndroidKeyStore AES-256, שנוצר ב-StrongBox כאשר למכשיר יש אחד כזה (אחרת TEE), עם setUserAuthenticationRequired(true) ותוקף אימות של 30 שניות לאחר אישור ביומטרי או אישור מכשיר, setUnlockedDeviceRequired(true), ו- setInvalidatedByBiometricEnrollment(true) שנותרו דולקים. הדגל האחרון הוא כנה ולא נושא עומס: אנדרואיד מיישמת אותו רק על מפתחות הדורשים אישור ביומטרי בכל שימוש, כך שבמפתח הזה של 30 שניות עם אישור המכשיר מותר, זה לא משנה דבר - מה שמרחיק זר הוא שרישום של מפתח דורש את קוד ה-PIN, והסרת נעילת המסך מבטלת את המפתח לתמיד. מפתחות Keystore אינם ניתנים לייצוא ואינם נכללים בגיבוי הענן של אנדרואיד. דומיין שאפליקציה שמה בשם בתצוגות שלה (webDomain) נחשב רק מדפדפן ידוע; מכל חבילה אחרת הוא חייב להיות גם כזה שהמערכת אימתה עבור אותה חבילה (Digital Asset Links), מכיוון שכל אפליקציה יכולה לתבוע כל דומיין.

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

3. קובץ הגיבוי

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

הקובץ הוא JSON וניתן לקריאה בכל עורך טקסט; רק טקסט מוצפן אטום. מי שימצא את הקובץ בעוד חמש שנים, לאחר שהאפליקציה נעלמה, יוכל לראות בדיוק כיצד הוא נחתם ולפתוח אותו באמצעות OpenSSL או כל ספריית Argon2 אחרת.

פורמט גרסה 1 (נשלח בגרסה 1.0, נשאר קריא)

{
  "format": "authbackup",
  "version": 1,
  "kdf": "PBKDF2-HMAC-SHA256",
  "rounds": 600000,
  "salt": "<base64, 16 bytes>",
  "cipher": "AES-256-GCM",
  "nonce": "<base64, 12 bytes>",
  "ciphertext": "<base64>",
  "tag": "<base64, 16 bytes>"
}
שלבבתים
keyPBKDF2-HMAC-SHA256(passphrase as UTF-8, salt, 600000 rounds, 32 bytes)
aadUTF-8("authbackup:1:600000:") ‖ salt (בייטים של מלח גולמי, לא base64)
ciphertext, tagAES-256-GCM(key, nonce, plaintext, aad); תג 16 בתים, מאוחסן בנפרד
plaintextUTF-8 JSON, מיון מפתחות: {"accounts":[…],"exportedAt":"…Z","passwords":[…],"version":1}

הערת תאימות: אנדרואיד 1.0 כתבה גרסה של גרסה 1 - kdf באותיות קטנות, ללא מפתח תג (תג 16 בייט המצורף לטקסט מוצפן), ללא נתונים נוספים. שתי הפלטפורמות ממשיכות לקרוא את הקבצים הללו (כאשר התג חסר: פצל את 16 הבייטים האחרונים, פתח עם AAD ריק; השווה kdf ללא תלות באותיות גדולות/קטנות) ושתיהן כותבות כעת רק את הפריסה שלמעלה.

פורמט גרסה 2 (נוכחי; ברירת המחדל לגיבויים חדשים)

{
  "format": "authbackup",
  "version": 2,
  "kdf": "Argon2id",
  "memoryKiB": 65536,
  "passes": 3,
  "lanes": 1,
  "salt": "<base64, 16 bytes>",
  "cipher": "AES-256-GCM",
  "nonce": "<base64, 12 bytes>",
  "ciphertext": "<base64>",
  "tag": "<base64, 16 bytes>"
}
שלבבתים
keyArgon2id(version 0x13, passphrase as UTF-8, salt, m = 65536 KiB, t = 3, p = 1, tagLength 32, no secret, no associated data)
aadUTF-8("authbackup:2:argon2id:65536:3:1:") ‖ salt
ciphertext, tagAES-256-GCM(key, nonce, plaintext, aad); תג 16 בתים, מאוחסן בנפרד
plaintextUTF-8 JSON, מיון מפתחות: {"accounts":[…],"cards":[…],"exportedAt":"…Z","passwords":[…],"version":2}

Argon2id הוא יישום C הייחוס (phc-winner-argon2, CC0), המשווק בשתי הפלטפורמות. 64 מגה-בייט ו-3 מעברים לוקחים כשנייה בטלפון נוכחי וגורמים לכל ניחוש לעלות את אותו הזיכרון והזמן בכל חומרה - התכונה שחסרה ל-PBKDF2 כנגד מתקני GPU, והסיבה לקיומו של v2. קורא מתעלם ממפתחות שהוא לא מכיר, כך שקורא v1 עם גוף v2 פשוט לעולם לא רואה כרטיסים.

הוכחה

שלושה קבצי וקטור-בדיקה (גיבוי גרסה 1, גיבוי גרסה 2 ו-Argon2id) נוצרים על ידי יישום שלישי, ללא תלות בשתי האפליקציות (OpenSSL של Node עבור PBKDF2 ו-AES-GCM, Argon2id של WebAssembly שנבדק בזמן היצירה מול התשובות שפורסמו של יישום הייחוס). כל אחד מהם מכיל את משפט הסיסמה, ה-salt, ה-nonce, הטקסט הרגיל, המפתח הנגזר, ה-AAD, הטקסט המוצפן והתג הצפויים, ואת הקובץ המלא. בדיקות היחידה ב-iOS וב-Android קוראות את אותם קבצים וקובעות את אותם בתים - כך שגיבוי חתום בפלטפורמה אחת מוכח, לא מונח, שנפתח באחרת, והסכם של שלושתם אינו שני עותקים של אותה טעות. כלי נלווה פותח קובץ שטלפון כתב בפועל עם אותו יישום שלישי ובודק את הכותרת מול הכללים לעיל (בדיוק המפתחות של הפורמט, כך שלא יכולים להיות רמז או שם; 16-byte salt, 12-byte nonce, 16-byte tag מאוחסנים בנפרד; גרסה 2 בדיוק ב-64 MiB / 3 / 1; סיסמה שגויה נדחתה); הריצה האוטומטית של iOS כותבת קובץ בסימולטור ופותחת אותו כך, ומחפשת במכל האפליקציות של הסימולטור, במכל קבוצת האפליקציות ובמסד הנתונים של מחזיקי המפתחות כל סיסמה ומספר כרטיס שנזרעו כ-UTF-8 ו-UTF-16 (0 תוצאות).

4. מודל האיום

מצבמה שיש להםמה שהם מקבלים
טלפון אבוד או נגנב, נעול מה שיש להםהמכשיר, קובץ מסד הנתונים, השורות האטומות מה שהם מקבליםטקסט מוצפן. מפתח העטיפה נמצא במובלעה המאובטחת / בוקס החזק ומשוחרר רק לאחר נעילת המכשיר בתוספת קוד ביומטרי או סיסמה חדשים. מחיקת הטלפון מרחוק (מצא את/מצא את המכשיר שלי) משמידה את חומר המפתח יחד איתו.
קובץ גיבוי גנוב מה שיש להםקובץ ה-.authbackup מחשבון ענן, דוא"ל, מחשב נייד מה שהם מקבליםגוף AES-256-GCM תחת מפתח הנגזר מסיסמה של לפחות 12 תווים, עם מלח לכל קובץ ו-Argon2id ב-64 MiB × 3 מעברים (v2) או PBKDF2 ב-600,000 סיבובים (v1). אין רמז, אין שם משתמש, אין רשימת חשבונות ברורה. כל ניחוש עולה על הגזירה המלאה; אין קיצור דרך. סיסמה חזקה היא כל ההגנה כאן, והאפליקציה מציינת זאת על הדף.
מכשיר גנוב כשהמסך לא נעול מה שיש להםטלפון בידך, לא נעול מה שהם מקבליםרשימת הקודים. הכספת (סיסמאות, כרטיסים) נמצאת מאחורי נעילת האפליקציה וננעלת מחדש על פי טיימר הנעילה האוטומטית (מיד / דקה אחת / 5 דקות); ערך מפוענח קיים בזיכרון רק כאשר המסך מציג אותו. מילוי אוטומטי וייצוא טקסט רגיל מבקשים מידע ביומטרי חדש גם כאשר האפליקציה פתוחה. הפעל את נעילת האפליקציה באמצעות "מיד" אם זה המקרה שמדאיג אותך.
אפליקציה זדונית באותו טלפון מה שיש להםארגז חול של אפליקציה אחרת, לוח הגזירים, נגישות או טריקים של שכבת-על מה שהם מקבליםהוא לא יכול לקרוא את הקבצים שלנו (ארגז חול בפלטפורמה) או להשתמש במפתח שלנו (המפתח קשור לזהות החתימה שלנו ולנוכחות המשתמש). עותקים נמחקים מהלוח לאחר 30 שניות; באנדרואיד העותק מסומן כרגיש ואינו נכלל בהיסטוריית הלוח. מסכי הכספת מוגדרים כ-FLAG_SECURE באנדרואיד (אין צילומי מסך, אין הקלטת מסך, ריק במחליף); iOS ריק את התמונה הממוזערת של המחליף. מילוי אוטומטי באנדרואיד מוגש רק לאפליקציות שהמערכת אימתה מול הדומיין השמור (קישורי נכסים דיגיטליים), כך שאפליקציה דומה לא מקבלת את הסיסמה שלך.
דף פישינג מה שיש להםאתר שנראה כמו זה ששמרת מה שהם מקבליםשום דבר לא מתמלא. ההתאמה מתבצעת לפי דומיין רישום (רשימת סיומות ציבורית, מצורפת ומעודכנת עם האפליקציה): login.example.com ו-example.com תואמים, example.com.evil.net ו-example1e.com לא. הדפדפן בתוך האפליקציה תואם באותו אופן וממלא רק את המסגרת שביקשה, לאחר בדיקה חוזרת מול מקורה של אותה מסגרת ברגע המילוי; מארח ללא דומיין רישום משלו - כתובת IP, שם גלוי ברשת המקומית - תואם בדיוק ושום דבר רופף יותר. מילוי אוטומטי של iOS מוסיף את בדיקת הדומיינים המשויכים של אפל. סיסמה שעליך להדביק ידנית לתוך סיסמה דומה עדיין מהווה סיכון; האפליקציה לא יכולה להסיר אותה, אלא רק להימנע מעזרה.
השרתים שלנו מה שיש להם— מה שהם מקבליםאין שרת כספת. ל-AssuredAuth אין חשבונות, אין כניסה ואין עותק של הכספת שלך, כך שאין שום דבר שלך בצד שלנו שאפשר לגנוב ולפרוץ. שני דברים אכן פועלים בצד השרת, ואף אחד מהם לא נוגע בכספת: תיבת דואר ממסר עבור הרחבת שולחן העבודה, המאחסנת מעטפות מוצפנות מקצה לקצה (קודים חד פעמיים, שנמחקים בעת הקריאה; לממסר אין מפתח לעולם), ושרתי היציאה של החיבור הפרטי האופציונלי, הנושאים תעבורה ואינם שומרים יומני גישה.
זימון לדין או בקשה ממשלתית מה שיש להםהליך משפטי שהופנה אלינו מה שהם מקבליםאין לנו מה למסור: אין לנו כספת, אין לנו מפתח, אין לנו סיסמה ואין לנו גיבוי. אפשר לאלץ אותנו לומר זאת; אי אפשר לאלץ אותנו לייצר את מה שלא קיים.

5. לוח כתיבה, צילומי מסך וזיכרון

6. מילוי אוטומטי: מה מתמלא ומה לא

איפהסיסמאותכרטיסים
iOS: ספארי ואפליקציות (הרחבת מילוי אוטומטי) סיסמאותכן, לאחר זיהוי פנים / מגע / קוד גישה חדש בתוסף (LAContext), ורק עבור הדומיין הניתן לרישום שעבורו הערך נשמר, עם בדיקת הדומיינים המשויכים של אפל עבור אפליקציות כרטיסיםלא. מילוי אוטומטי של כרטיסים בספארי הוא רק של אפל; מסך הכרטיס אומר "מילוי בדפדפן AssuredAuth ועם עותק" ולא מבטיח שום דבר מעבר לכך.
אנדרואיד: אפליקציות וכרום (שירות מילוי אוטומטי) סיסמאותכן, אימות לפי מערך נתונים: המערכת מציגה את BiometricPrompt לפני המילוי; חבילת האפליקציה תואמת רק כאשר Digital Asset Links מקשרת אותה לדומיין השמור. כרטיסיםכן, הרמזים creditCardNumber, creditCardExpiration* ו-creditCardSecurityCode, אותו שער ביומטרי
דפדפן AssuredAuth (בשתי הפלטפורמות) סיסמאותכן, לפי דומיין רישום - מארח שאין לו התאמות מדויקות - לתוך המסגרת ששאלה, ביומטרי לפני המילוי כרטיסיםכן, באמצעות זיהוי שדה, ביומטרי לפני המילוי
העתקת כפתורים סיסמאותמאחורי נעילת האפליקציה, לוח כתיבה של 30 שניות כרטיסיםמספר, תפוגה, קוד CVC (אותם כללים)

שום דבר לא מתמלא על מארח דומה. שום דבר לא מתמלא בלי מידע ביומטרי.

7. מה שלעולם לא קורה

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

8. מפני מה איננו יכולים להגן

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

9. סטטוס סקירה

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

10. היכן הדברים פועלים

שום דבר מהכספת לא עוזב את הטלפון, אבל כמה דברים סביבה כן רצים על מחשבים של אנשים אחרים. זוהי הרשימה, ומה כל אחד מהם מכיל; זרימת הנתונים עצמה מתוארת במדיניות הפרטיות בכתובת https://assuredauth.com/privacy.

כל אחד מהם מכיל את מה שכתוב בשורה שלו ושום דבר מהכספת. הרשימה משתנה כאשר המוצר משתנה, וסעיף זה משתנה יחד איתו.

דיווח על חולשה

אם אתם סבורים שמצאתם חולשה במשהו המתואר כאן, כתבו לכתובת hello@assuredauth.com עם הנושא "אבטחה". אנא ציינו את הפלטפורמה, גרסת האפליקציה והשלבים; מספיקה הוכחה המשתמשת בנתונים שלכם, ואנו מבקשים שלא לבצע בדיקות מול נתונים של אנשים אחרים. איננו מציעים מפתח PGP; אם דיווח לא אמור להגיע בדוא"ל רגיל, ציינו זאת בהודעה הראשונה ונתאם דרך אחרת.

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

במסגרת: אפליקציות iOS ואנדרואיד, אפליקציות השעון, תוסף שולחן העבודה, assuredauth.com וה-API שלו. מחוץ למסגרת: חנות האפליקציות וגוגל פליי עצמם, הספקים המפורטים לעיל, הנדסה חברתית של כל אחד ומניעת שירות.

אין פרס כרגע. דיווח נענה בתיקון ובתודה, לא בכסף.