KeyStore (Android): المفاهيم الأساسية وAPI وكيفية عمل التخزين المشفر

المؤلف: IT Sectr نُشر: 2026-03-14 وقت القراءة: 10 دق

KeyStore (Android) هو تطبيق للمزوّد المشفر لهندسة Java Cryptography Architecture (JCA) المدمج في Android للتخزين الآمن للمفاتيح مع إمكانية العزل عبر الأجهزة. منذ Android 4.3 (API 18)، يدعم KeyStore المفاتيح العتادية عبر Keymaster HAL، وابتداءً من Android 9 (API 28) يدعم StrongBox Keymaster للمفاتيح في العنصر الآمن المخصص. وفقًا لـ توثيق أمان Android، فإن المزوّد «AndroidKeyStore» يحل محل Bouncy Castle أو OpenSSL KeyStore القياسي، مما يوفر حماية على مستوى النظام ضد الاستخراج غير المصرح به للمفاتيح.

الملامح الرئيسية

  • Android KeyStore هو مزوّد JCA لتخزين المفاتيح مع دعم TEE وStrongBox والحماية البيومترية
  • KeyGenParameterSpec يحدد الخوارزمية والغرض وdigest وpadding والبيومترية عند إنشاء المفتاح
  • Keymaster HAL ينفذ العمليات المشفرة العتادية على مستويات Software وTEE وStrongBox
  • Key Attestation (API 28+) يسمح للخادم بالتحقق من أن المفتاح تم إنشاؤه في بيئة عتادية لـ Android KeyStore
  • الاسم المستعار للمفتاح هو سلسلة يستخدمها التطبيق للوصول إلى المفتاح في Keystore؛ اسم مستعار واحد يقابل مفتاحًا واحدًا

ما هو KeyStore في Android؟

KeyStore في Android ليس تطبيقًا أو ملفًا منفصلاً، بل هو مزوّد مشفر يطبق واجهة java.security.KeyStore. يوفر API موحدة لتخزين واستخدام المفاتيح الخاصة والمفاتيح المتماثلة وشهادات CA الموثوقة. يتم تسجيل المزوّد باسم «AndroidKeyStore» ويمكن الوصول إليه عبر KeyStore.getInstance() القياسي.

تطور Android KeyStore

قبل Android 4.3، كانت العمليات المشفّرة تُنفذ عبر Bouncy Castle. قدم Android 4.3 Keymaster HAL 1.0، مما أتاح استخدام TEE على ARM TrustZone. أضاف Android 6.0 (API 23) Keymaster 2.0 مع المصادقة البيومترية العتادية. قدم Android 9 (API 28) Keymaster 4.0 وStrongBox Keymaster للعنصر الآمن المخصص.

كل إصدار من Keymaster يضيف قدرات جديدة ويحسن عزل المفاتيح. الأجهزة الحديثة (2022+) يجب أن تدعم Keymaster 4.0 للحصول على شهادة Google Mobile Services، مما يضمن توفر TEE لجميع تطبيقات Android.

الهندسة المعمارية والمكونات

يتكون Android KeyStore من ثلاث طبقات: Java API (KeyStore, KeyPairGenerator)، عملية النظام keystore (C++، تعمل كخدمة نظام)، وKeymaster HAL (مكتبة في TEE أو Secure Element). يستدعي التطبيق API، ويوجّه خدمة keystore الطلب إلى Keymaster، ويتم تنفيذ العملية في البيئة الآمنة.

جميع المفاتيح الخاصة تُخزّن في TEE ولا يمكن قراءتها من مساحة المستخدم. حتى خدمة keystore للنظام لا تملك الوصول إلى المفاتيح الخام — فقط إلى المقابض التي تشير إلى المفاتيح داخل Keymaster.

كيف يعمل KeyStore كمزوّد مشفر؟

يطبق Android KeyStore واجهة مزوّد الخدمة القياسية JCA. عندما يستدعي التطبيق Cipher.getInstance(«RSA/ECB/PKCS1Padding», «AndroidKeyStore»)، يفوض مزوّد أمان Android العملية إلى Keymaster عبر السلسلة: Java → JNI → خدمة keystore → Keymaster HAL.

تسجيل المزوّد

يتم تسجيل المزوّد AndroidKeyStore تلقائيًا عند بدء العملية. أولويته أعلى من Bouncy Castle أو Conscrypt. لذلك عند استدعاء KeyStore.getInstance() دون تحديد مزوّد، يتم إرجاع AndroidKeyStore في معظم الحالات. للاستدعاء الصريح، استخدم KeyStore.getInstance(«AndroidKeyStore»).

كل تطبيق Android لديه حاوية معزولة في KeyStore. التطبيقات التي لها نفس UID (shared userId) يمكنها مشاركة الوصول إلى مفاتيح معينة، لكن الإعداد القياسي يضمن أن التطبيق A لا يمكنه قراءة مفاتيح التطبيق B.

طرق KeyStore وخصائصها

load(null) — تهيئة KeyStore. المعلمة دائمًا null لـ AndroidKeyStore. setEntry — يحفظ مفتاحًا مع KeyProtection المحددة (الأغراض، digest، padding). getEntry — يسترجع KeyStore.PrivateKeyEntry أو SecretKeyEntry أو TrustedCertificateEntry. containsAlias — يتحقق من وجود المفتاح. deleteEntry — يحذف المفتاح بشكل دائم.

kotlin
import java.security.KeyStore
import java.security.KeyPairGenerator
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties

object KeyStoreManager {
    private val keyStore by lazy {
        KeyStore.getInstance("AndroidKeyStore").apply { load(null) }
    }

    fun createRsaKey(alias: String) {
        val spec = KeyGenParameterSpec.Builder(alias,
            KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY
        ).setKeySize(2048)
         .setDigests(KeyProperties.DIGEST_SHA256)
         .setSignaturePaddings(KeyProperties.SIGN_PADDING_RSA_PKCS1)
         .build()

        val kpg = KeyPairGenerator.getInstance(
            KeyProperties.KEY_ALGORITHM_RSA,
            "AndroidKeyStore"
        )
        kpg.initialize(spec)
        kpg.generateKeyPair()
    }
}

الخوارزميات وأنواع المفاتيح المدعومة

يدعم Android KeyStore مجموعة واسعة من الخوارزميات المشفرة، تختلف حسب إصدار Keymaster HAL على الجهاز. يمكن للمطور الحصول على قائمة الخوارزميات المدعومة عبر KeyGenParameterSpec.Builder عند محاولة الإنشاء — المعلمات غير المتوافقة ترمي InvalidAlgorithmParameterException.

الخوارزميات غير المتماثلة

RSA (1024–4096 بت) — للتوقيع (PKCS1, PSS مع SHA-1/SHA-256/SHA-384/SHA-512) والتشفير (OAEP مع SHA-1/SHA-256). EC (P-224, P-256, P-384, P-521) — لتوقيع ECDSA واتفاق المفاتيح ECDH. X25519 وEd25519 — منذ Android 12 (API 31) للبروتوكولات المشفرة الحديثة.

للمفاتيح غير المتماثلة، أنشئ دائمًا داخل Keymaster، ولا تستورد أبدًا المفاتيح الخاصة. المفاتيح الخاصة المستوردة ليست محمية عتاديًا — يتم تخزينها في طبقة البرمجيات وتكون عرضة للخطر عند اختراق عملية التطبيق.

الخوارزميات المتماثلة

AES (128, 256 بت) — للتشفير المتماثل في أوضاع CBC, CTR, GCM. HMAC (SHA-1, SHA-256, SHA-512) — لمصادقة الرسائل. ChaCha20 (Android 12+) — لتشفير التدفق عالي الأداء مع مصادقة Poly1305.

الخوارزميةKeymasterالغرضAPI
RSAKM 1.0+التوقيع، التشفير18+
ECKM 1.0+ECDSA, ECDH18+
AESKM 2.0+التشفير المتماثل23+
HMACKM 2.0+رمز المصادقة23+
ChaCha20KM 3.0+تشفير التدفق31+
X25519/Ed25519KM 3.0+تبادل المفاتيح31+

أنواع المفاتيح وتسلسلها

KeyStore.PrivateKeyEntry — يحتوي على مفتاح خاص (غير قابل للتصدير) وسلسلة شهادات. KeyStore.SecretKeyEntry — للمفاتيح المتماثلة. KeyStore.TrustedCertificateEntry — لشهادات CA الموثوقة. يمكن تصدير المفاتيح العامة عبر keyStore.getCertificate(alias).publicKey.

أمثلة على إنشاء المفاتيح واستخدامها

لننظر إلى سيناريو كامل: إنشاء مفتاح AES لتشفير البيانات وإنشاء مفتاح EC للتوقيع مع حماية بيومترية. يتم إنشاء كلا المفتاحين داخل Android KeyStore مع دعم عتادي.

إنشاء مفتاح AES للتشفير

يتم إنشاء مفتاح AES عبر KeyGenerator مع KeyGenParameterSpec. المعلمات: PURPOSE_ENCRYPT + PURPOSE_DECRYPT, BLOCK_MODE_GCM (الوضع الموصى به مع المصادقة), ENCRYPTION_PADDING_NONE (لا حاجة للpadding لـ GCM).

kotlin
import javax.crypto.KeyGenerator
import javax.crypto.Cipher
import javax.crypto.spec.GCMParameterSpec

fun generateAndEncrypt(alias: String, plainText: ByteArray): ByteArray {
    val spec = KeyGenParameterSpec.Builder(alias,
        KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
    ).setBlockModes(KeyProperties.BLOCK_MODE_GCM)
     .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
     .setKeySize(256)
     .build()

    val kg = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
    kg.initialize(spec)
    kg.generateKey()

    val cipher = Cipher.getInstance("AES/GCM/NoPadding")
    cipher.init(Cipher.ENCRYPT_MODE, getKeyFromStore(alias))
    return cipher.doFinal(plainText)
}

التوقيع مع الحماية البيومترية

مفتاح EC مع userAuthenticationRequired=true يتطلب مصادقة المستخدم قبل كل عملية توقيع. يُستخدم BiometricPrompt مع CryptoObject الذي يحتوي على كائن Signature لهذا الغرض. بعد التحقق البيومتري الناجح، يسمح Keymaster بالعملية.

kotlin
fun createBiometricSignKey(alias: String) {
    val spec = KeyGenParameterSpec.Builder(alias,
        KeyProperties.PURPOSE_SIGN
    ).setAlgorithmParameterSpec(
        ECGenParameterSpec("secp256r1")
    ).setDigests(KeyProperties.DIGEST_SHA256)
     .setUserAuthenticationRequired(true)
     .setInvalidatedByBiometricEnrollment(true)
     .build()

    val kpg = KeyPairGenerator.getInstance(
        KeyProperties.KEY_ALGORITHM_EC,
        "AndroidKeyStore"
    )
    kpg.initialize(spec)
    kpg.generateKeyPair()
}

KeyStore والأمان على الجهاز

يوفر Android KeyStore ضمانات أمان على مستوى العتاد لا تستطيع KeyStore البرمجية (JKS, BKS) توفيرها. المفاتيح محمية على مستوى SoC، وحتى السيطرة الكاملة على مساحة مستخدم Android لا تسمح باستخراج المفتاح الخاص.

Key Attestation (Android 8.1+)

Key Attestation هي آلية تسمح للتطبيق (والخادم) بالتحقق من البيئة التي تم إنشاء المفتاح فيها. يوقع Android Keystore شهادة تحتوي على قائمة خصائص المفتاح: الخوارزمية، الحجم، الأغراض، العتادي (True/False)، المنشأ (GENERATED, IMPORTED). يتحقق الخادم من سلسلة الشهادات حتى الشهادة الجذرية لـ Google.

هذا أمر بالغ الأهمية للتطبيقات المالية: يمكن للخادم أن يطلب أن يكون المفتاح قد تم إنشاؤه في بيئة عتادية (Hardware-Backed = True) ويرفض المفاتيح المنشأة في Keystore برمجي. تمنع Key Attestation الهجمات التي يستبدل فيها المهاجم Keystore بمحاكي.

إبطال المفاتيح عند تغيير البيانات البيومترية

setInvalidatedByBiometricEnrollment(true) يعني أن Keymaster سيحذف المفتاح تلقائيًا عند تغيير أو إزالة القوالب البيومترية للمستخدم. هذه حماية من الهجمات التي يضيف فيها المهاجم بصمة إصبعه إلى حساب موجود. بعد إضافة بصمة جديدة، تصبح المفاتيح القديمة غير قابلة للوصول.

عداد محاولات المصادقة البيومترية الفاشلة يُدار أيضًا بواسطة Keymaster. بعد maxBiometricAttempt (قابل للتعديل من قبل الشركة المصنعة، عادةً 5)، يحجب Keymaster جميع العمليات باستخدام المفاتيح البيومترية لمدة 30 ثانية. بعد 10 محاولات فاشلة — حتى إدخال كلمة مرور الجهاز (PIN السري).

الأسئلة الشائعة

ما الفرق بين Android KeyStore وBouncy Castle KeyStore؟

Bouncy Castle (BKS) هو KeyStore برمجي يخزن المفاتيح في ملف محمي بكلمة مرور. Android KeyStore يستخدم العزل العتادي TEE/StrongBox. يمكن استخراج مفاتيح BKS مع الوصول الجذري، أما مفاتيح Android KeyStore فلا يمكن. BKS مناسب لشهادات CA، Android KeyStore للمفاتيح الخاصة.

هل يمكن استخدام مفتاح واحد للتشفير والتوقيع؟

نعم، إذا حددت PURPOSE_ENCRYPT أو PURPOSE_DECRYPT أو PURPOSE_SIGN أو PURPOSE_VERIFY عند الإنشاء. لكن أفضل الممارسات هي إنشاء مفاتيح منفصلة لعمليات مختلفة. هذا يحد من الضرر إذا تم اختراق أحد المفاتيح ويتوافق مع مبدأ الامتياز الأقل.

كيف أعرف إذا كان المفتاح عتاديًا في Android KeyStore؟

استخدم KeyStore.getKeyCharacteristics(alias) المتاح عبر android.security.keystore. تعيد الطريقة مجموعة من الأعلام: FLAG_HARDWARE — مفتاح في TEE، FLAG_SECURE_ELEMENT — مفتاح في StrongBox. إذا لم تكن هناك أعلام، فالمفتاح برمجي فقط.

ماذا يحدث عند إزالة جميع القوالب البيومترية؟

جميع المفاتيح التي تم إنشاؤها مع setInvalidatedByBiometricEnrollment(true) سيتم إبطالها تلقائيًا بواسطة Keymaster. عند محاولة استخدامها، سيتلقى التطبيق KeyPermanentlyInvalidatedException. البيانات المشفرة بهذه المفاتيح ستفقد بشكل دائم.

هل يدعم Android KeyStore النسخ الاحتياطي للمفاتيح؟

المفاتيح العتادية (في TEE/StrongBox) لا تدعم النسخ الاحتياطي — فهي مرتبطة بجهاز معين. المفاتيح البرمجية يمكن تضمينها في نسخة Google Drive الاحتياطية. لنقل البيانات بين الأجهزة، قم بتشفير البيانات على الخادم وفك تشفيرها على الجهاز الجديد.

الملخص

  • Android KeyStore — مزوّد JCA لتخزين المفاتيح المعزول عتاديًا عبر Keymaster HAL في TEE/StrongBox
  • KeyGenParameterSpec يهيئ الخوارزمية والحجم والأغراض وdigest والبيومترية والقيود الزمنية للمفتاح
  • RSA (KM 1.0+), EC (KM 1.0+), AES (KM 2.0+), ChaCha20 (KM 3.0+) — خوارزميات مدعومة بمستويات Keymaster مختلفة
  • Key Attestation (API 28+) يسمح للخادم بالتحقق من المنشأ العتادي للمفتاح
  • حماية بيومترية للمفاتيح عبر setUserAuthenticationRequired + BiometricPrompt مع CryptoObject
  • إبطال المفاتيح عند تغيير البيانات البيومترية يمنع الاستخدام غير المصرح به لبصمات الأصابع المضافة
  • استخدم Android KeyStore لإنشاء وتخزين المفاتيح المشفرة مع حماية عتادية في تطبيقات Android

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا