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 για κλειδιά σε αφιερωμένο Secure Element. Σύμφωνα με Android Security Documentation, ο παρόχος “AndroidKeyStore” αντικαθιστά τα τυπικά Bouncy Castle ή OpenSSL KeyStore, παρέχοντας συστημική προστασία από την μη εξουσιοδοτημένη εξαγωγή κλειδιών.

Βασικά σημεία

  • Android KeyStore — παρόχος JCA για αποθήκευση κλειδιών με υποστήριξη TEE, StrongBox και βιομετρικής προστασίας
  • KeyGenParameterSpec καθορίζει αλγόριθμο, σκοπό, digest, padding και βιομετρία κατά τη δημιουργία κλειδιού
  • Keymaster HAL εκτελεί υλικές κρυπτογραφικές λειτουργίες σε επίπεδα Software, TEE και StrongBox
  • Key Attestation (API 28+) επιτρέπει στον διακομιστή να επαληθεύσει ότι το κλειδί δημιουργήθηκε σε υλικό περιβάλλον Android KeyStore
  • Alias κλειδιού — το συμβολοσειρά με το οποίο η εφαρμογή προσπελάζει το κλειδί στο Keystore; ένα alias αντιστοιχεί σε ένα κλειδί

Τι είναι το 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 για αφιερωμένο Secure Element.

Κάθε έκδοση του Keymaster προσθέτει νέες δυνατότητες και βελτιώνει την απομόνωση κλειδιών. Οι σύγχρονες συσκευές (2022+) πρέπει να υποστηρίζουν Keymaster 4.0 για πιστοποίηση Google Mobile Services, πράγμα που εγγυάται την παρουσία TEE για όλες τις εφαρμογές Android.

Αρχιτεκτονική και συστατικά

Το Android KeyStore αποτελείται από τρία επίπεδα: Java API (KeyStore, KeyPairGenerator), η διεργασία συστήματος keystore (C++, λειτουργεί ως system service) και Keymaster HAL (βιβλιοθήκη σε TEE ή Secure Element). Η εφαρμογή καλεί το API, η υπηρεσία keystore διοχετεύει το αίτημα στο Keymaster, η λειτουργία εκτελείται σε προστατευμένο περιβάλλον.

Όλα τα ιδιωτικά κλειδιά αποθηκεύονται σε TEE και δεν μπορούν να διαβαστούν από τον χώρο χρήστη. Ακόμη και η υπηρεσία συστήματος keystore δεν έχει πρόσβαση σε αδρά κλειδιά — μόνο σε χειριστές που δείχνουν σε κλειδιά μέσα στο Keymaster.

Πώς λειτουργεί το KeyStore ως κρυπτογραφικός παρόχος;

Το Android KeyStore υλοποιεί τη τυπική διεπαφή παρόχου υπηρεσιών JCA. Όταν η εφαρμογή καλεί Cipher.getInstance(“RSA/ECB/PKCS1Padding”, “AndroidKeyStore”), ο Android Security Provider αναθέτει τη λειτουργία στο Keymaster μέσω της αλυσίδας: Java → JNI → keystore service → 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 (purposes, 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 bit) — για υπογραφή (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, ΠΟΤΕ μην εισάγετε ιδιωτικά κλειδιά. Τα εισαγόμενα ιδιωτικά κλειδιά δεν προστατεύονται υλικά — αποθηκεύονται στο επίπεδο λογισμικού και είναι ευάλωτα σε περίπτωση συμβιβασμού AP.

Συμμετρικοί αλγόριθμοι

AES (128, 256 bit) — για συμμετρική κρυπτογράφηση σε λειτουργίες 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/E25519KM 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 (για GCM δεν χρειάζεται padding).

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 υπογράφει ένα πιστοποιητικό που περιέχει λίστα χαρακτηριστικών κλειδιού: αλγόριθμο, μέγεθος, purges, hardware-backed (True/False), origin (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 μπορούν να εξαχθούν με root πρόσβαση, τα κλειδιά Android KeyStore όχι. Το BKS είναι κατάλληλο για πιστοποιητικά CA, το Android KeyStore για ιδιωτικά κλειδιά.

Μπορεί ένα κλειδί να χρησιμοποιηθεί για κρυπτογράφηση και υπογραφή;

Ναί, εάν κατά τη δημιουργία καθοριστεί PURPOSE_ENCRYPT or PURPOSE_DECRYPT or PURPOSE_SIGN or 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 διαμορφώνει τον αλγόριθμο, το μέγεθος, τα purges, το 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. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης