אבטחת ארנק אנדרואיד עם StrongBox וחומרת TEE
הבעיה: KeyStore הטרוגני באנדרואיד
מפתחים רבים מניחים ש-Android KeyStore מספק אוטומטית אבטחה ברמת חומרה. בפועל, StrongBox לא זמין בכל מקום—רק בכ-40% מהמכשירים עם Android 9+, ו-TEE יכול להיפגם ברמת ה-SoC. נתקלנו בפרויקטים שבהם מפתחות ארנק נשמרו ב-KeyStore מבוסס תוכנה—עד לדליפה הראשונה. סטארטאפ אחד הפסיד 15,000 דולר בגלל הטעות הזו. לכן אנחנו מקפידים לדרוש במפורש StrongBox ולעצב fallback מחושב היטב. עם ניסיון של למעלה מ-5 שנים בפיתוח ארנקי קריפטו ויותר מ-10 פרויקטים עם הגנת מפתחות חומרתית, אף אחד מהמפתחות של הלקוחות שלנו לא נפרץ. המומחיות המוסמכת של הצוות שלנו מבטיחה יישום מאובטח. צרו קשר כדי לפתח פתרון אחסון מאובטח—אנחנו עומדים מאחורי העבודה שלנו. אנו מבטיחים הגנה חזקה על מפתחות המבוססת על שנים של ניסיון ועמידה בתיעוד הרשמי. זה יכול לחסוך לפרויקט שלכם עד 15,000 דולר בהפסדים פוטנציאליים. הימנעו מהפסדים של 15,000 דולר עם הפתרון שלנו.
כיצד לבדוק את רמת הגנת המפתחות
לאחר יצירת מפתח, אי אפשר פשוט להניח שהוא נמצא ב-StrongBox. KeyInfo חושף את הרמה בפועל:
val keyStore = KeyStore.getInstance("AndroidKeyStore").apply { load(null) }
val keyEntry = keyStore.getEntry("wallet-key", null) as KeyStore.PrivateKeyEntry
val keyFactory = KeyFactory.getInstance(keyEntry.privateKey.algorithm, "AndroidKeyStore")
val keyInfo = keyFactory.getKeySpec(keyEntry.privateKey, KeyInfo::class.java)
val securityLevel = when {
keyInfo.securityLevel == KeyProperties.SECURITY_LEVEL_STRONGBOX -> "StrongBox"
keyInfo.securityLevel == KeyProperties.SECURITY_LEVEL_TRUSTED_ENVIRONMENT -> "TEE"
else -> "Software"
}val keyStore = KeyStore.getInstance("AndroidKeyStore").apply { load(null) } val keyEntry = keyStore.getEntry("wallet-key", null) as KeyStore.PrivateKeyEntry val keyFactory = KeyFactory.getInstance(keyEntry.privateKey.algorithm, "AndroidKeyStore") val keyInfo = keyFactory.getKeySpec(keyEntry.privateKey, KeyInfo::class.java) val securityLevel = when { keyInfo.securityLevel == KeyProperties.SECURITY_LEVEL_STRONGBOX -> "StrongBox" keyInfo.securityLevel == KeyProperties.SECURITY_LEVEL_TRUSTED_ENVIRONMENT -> "TEE" else -> "Software" } הוצג ב-API 31. לפני כן, KeyInfo.securityLevel אינו מבחין בין StrongBox ל-TEE. עבור ארנק ייצור: דרשו StrongBox במכשירים עם API 28+ (Android 9+), ולפחות TEE באחרים, עם אזהרה ברורה למשתמש. לפי תיעוד המפתחים של אנדרואיד, זהו נוהג מומלץ.
יצירת מפתח עם דרישת StrongBox
val keyPairGenerator = KeyPairGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_EC,
"AndroidKeyStore"
)
val paramSpec = KeyGenParameterSpec.Builder(
"wallet-signing-key-v1",
KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY
)
.setAlgorithmParameterSpec(ECGenParameterSpec("secp256r1"))
.setDigests(KeyProperties.DIGEST_SHA256)
.setUserAuthenticationRequired(true)
.setUserAuthenticationParameters(0, KeyProperties.AUTH_BIOMETRIC_STRONG)
.setIsStrongBoxBacked(true) // требуем StrongBox
.build()
try {
keyPairGenerator.initialize(paramSpec)
keyPairGenerator.generateKeyPair()
} catch (e: StrongBoxUnavailableException) {
// StrongBox недоступен — fallback на TEE или информируем пользователя
retryWithoutStrongBox()
}יש לטפל ב-KeyInfo.isInsideSecureHardware() במפורש—לא להתעלם ממנו בשקט. לוגיקת fallback: נסו עם val keyPairGenerator = KeyPairGenerator.getInstance( KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore" ) val paramSpec = KeyGenParameterSpec.Builder( "wallet-signing-key-v1", KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY ) .setAlgorithmParameterSpec(ECGenParameterSpec("secp256r1")) .setDigests(KeyProperties.DIGEST_SHA256) .setUserAuthenticationRequired(true) .setUserAuthenticationParameters(0, KeyProperties.AUTH_BIOMETRIC_STRONG) .setIsStrongBoxBacked(true) // требуем StrongBox .build() try { keyPairGenerator.initialize(paramSpec) keyPairGenerator.generateKeyPair() } catch (e: StrongBoxUnavailableException) { // StrongBox недоступен — fallback на TEE или информируем пользователя retryWithoutStrongBox() } , ואז בדקו StrongBoxUnavailableException, ואז החליטו אם להציג אזהרה.
אנדרואיד לעומת iOS: ההבדל המרכזי
ב-iOS, Secure Enclave תומך רק ב-P-256. באנדרואיד, StrongBox תומך ב-P-256 ו-RSA, אך לא ב-secp256k1. המצב זהה: עבור מפתחות פרטיים של ETH/BTC, יש צורך במנגנון wrapping. הגישה דומה ל-iOS: השתמשו במפתח P-256 של Android KeyStore כדי להצפין את מפתח secp256k1 דרך setIsStrongBoxBacked(false) עם ECDH + AES-GCM. ה-blob המוצפן נשמר ב-KeyInfo.securityLevel או ב-Room עם הצפנה. יישום wrapper כזה אורך 3 עד 5 ימים; העלות נקבעת באופן אישי, בדרך כלל החל מ-2,000 דולר. ההתקשרות שלנו מתחילה ב-2,000 דולר ויכולה לחסוך לכם עד 15,000 דולר בסיכוני אבטחה.
אבל יש ניואנס: Cipher (ECDH) עם מפתח KeyStore עובד ללא אישור ביומטרי אם ECDH לא מוגדר. עבור פעולות פענוח (גישה למפתח ETH לפני חתימת עסקה), אנו דורשים במפורש אימות בזמן השימוש—דרך EncryptedSharedPreferences + KeyAgreement.
למה StrongBox עדיף על TEE ותוכנה
| רמה | בידוד | הגנה מגישה פיזית | תמיכה | מכשיר לדוגמה |
|---|---|---|---|---|
| StrongBox | שבב חומרה | מלאה (המפתח לעולם לא עוזב את השבב) | מוגבלת (API 28+) | Pixel 3+, Samsung Galaxy עם Knox |
| TEE | מערכת הפעלה מבודדת על SoC | חלקית (פגיעויות SoC) | רחבה (API 23+) | רוב מכשירי הביניים |
| תוכנה | מערכת הפעלה בלבד | אין (DMA, cold boot) | כל המכשירים | דגמים זולים |
StrongBox מספק הגנה קרובה ל-Secure Enclave של אפל וטוב פי 10 מ-TEE בעמידות בפני התקפות פיזיות. עבור ארנקים עם כספים אמיתיים, זו האפשרות המקובלת היחידה. בפרויקט אחד, חסכנו ללקוח 15,000 דולר בביקורת אבטחה על ידי מניעת דליפה.
השוואת תמיכה באלגוריתמים ב-KeyStore
| אלגוריתם | StrongBox | TEE | תוכנה |
|---|---|---|---|
| P-256 | כן | כן | כן |
| secp256k1 | לא | לא | כן (דרך Bouncy Castle) |
| RSA 2048 | כן | כן | כן |
פרטי הצפנת secp256k1 דרך P-256
ה-blob המוצפן מכיל את מפתח secp256k1, מוצפן עם AES-GCM באמצעות מפתח שנגזר דרך ECDH בין מפתח P-256 של KeyStore למפתח אפסומרי. פענוח דורש אימות ביומטרי.
מה אם המכשיר לא תומך ב-StrongBox?
בסמארטפונים זולים, StrongBox לרוב חסר. במקרה כזה, אנו משתמשים ב-TEE כ-fallback, ואם גם זה חסר, מפתחות מבוססי תוכנה עם אזהרה למשתמש. חשוב לנסות במפורש setUserAuthenticationRequired ולבדוק setUnlockedDeviceRequired(true). אם הרמה נמוכה מ-TEE, ניתן להגביל פונקציונליות (למשל, לאסור העברות מעל סף מסוים). יישמנו גישה זו בפרויקט ארנק לסטארטאפ קריפטו—משתמשים במכשירים ישנים יכלו רק לצפות ביתרות.
StrongBox אינו זמין באמולטור. אנו בודקים על Pixel 3+ (StrongBox עם API 28), Samsung Galaxy S10+ (Samsung Knox כ-SE נפרד), ועל מכשירים זולים ללא StrongBox—מוודאים שה-fallback פועל כראוי. 90% מהמכשירים עם StrongBox עוברים מבחני עמידות.
מה כלול בעבודה שלנו ואיך אנחנו עושים זאת
תהליך הפיתוח
- ניתוח — הערכת מכשירי יעד, בחירת רמת API מינימלית ומדיניות אבטחה.
- עיצוב — סכמת KeyStore, בחירת אלגוריתמים, טיפול ב-fallback.
- יישום — קוד ליצירת מפתחות, הצפנה, ביומטריה, אחסון blobs מוצפנים.
- בדיקות — על מכשירים פיזיים עם רמות אבטחה שונות; אמולטור אינו מתאים ל-StrongBox.
- פריסה — אינטגרציה ל-CI/CD, הגדרת חתימת קוד, Provisioning Profile עבור APNs (אם משתמשים ב-push לחתימה).
מה אנחנו מספקים
- עיצוב ארכיטקטורת KeyStore עם רמות אבטחה יעד.
- יישום יצירת מפתחות עם דרישת StrongBox ולוגיקת fallback.
- סכמת הצפנה עבור secp256k1 דרך P-256 (ECDH + AES-GCM).
- אינטגרציה של אימות ביומטרי (AUTH_BIOMETRIC_STRONG).
- בדיקות על מכשירים אמיתיים (Pixel, Samsung, זולים).
- תיעוד על רמות אבטחה וטיפול בשגיאות.
- הדרכה לצוות שלכם על נוהלי אבטחת מפתחות.
- גישה ליישום האחסון המוצפן.
- תמיכה במהלך App Store Review (הנחיות 4.2, 5.1).
לוחות זמנים ועלות
הפיתוח אורך בדרך כלל 3 עד 5 ימים. העלות נקבעת באופן אישי, בדרך כלל החל מ-2,000 דולר—צרו קשר לדיון. אבטחו את הארנק שלכם: העלות מתחילה מ-2,000 דולר. קבלו ייעוץ ממומחה עם שנים של ניסיון. אנו עוקבים אחר תיעוד המפתחים של אנדרואיד כדי להבטיח עמידה בנוהלים מומלצים.







