Secure Storage w aplikacjach mobilnych: co to jest, metody i implementacja

Autor: IT Sectr Opublikowano: 2026-04-04 Czas czytania: 9 min

Secure Storage (bezpieczne przechowywanie) — zespół metod i technologii ochrony poufnych danych na urządzeniu: tokenów, kluczy szyfrujących, informacji płatniczych i danych osobowych użytkowników. Według OWASP Mobile Top 10 (2024), niebezpieczne przechowywanie danych znajduje się w pierwszej trójce najpoważniejszych zagrożeń. Prawidłowa implementacja bezpiecznego przechowywania zapobiega wyciekom danych nawet przy fizycznym dostępie do urządzenia.

Najważniejsze

  • Secure Storage — zestaw metod szyfrowania i izolacji danych na urządzeniu zapobiegających dostępowi ze strony innych aplikacji i atakujących.
  • Android Keystore — magazyn kryptograficzny generujący i chroniący klucze na poziomie sprzętowym (TEE).
  • iOS Keychain — zabezpieczona baza danych do przechowywania sekretów, zaszyfrowana na poziomie systemu operacyjnego z dostępem przez Security framework.
  • EncryptedSharedPreferences — biblioteka Android Jetpack do szyfrowania par klucz-wartość z wykorzystaniem AES-256.
  • Data Protection API — mechanizm iOS szyfrujący pliki na podstawie klasy ochrony powiązanej ze stanem blokady urządzenia.

Czym jest Secure Storage?

Secure Storage — praktyka przechowywania poufnych danych aplikacji mobilnej w taki sposób, aby były niedostępne dla innych aplikacji, złośliwego oprogramowania i atakującego przy fizycznym dostępie do urządzenia. W przeciwieństwie do zwykłego przechowywania, Secure Storage wykorzystuje szyfrowanie, izolację i ochronę sprzętową.

Nie wszystkie dane wymagają Secure Storage: obrazy profilowe czy pamięć podręczna wiadomości mogą być przechowywane w zwykłym systemie plików. Jednak klucze szyfrujące, tokeny uwierzytelniające, dane płatnicze, klucze prywatne i szablony biometryczne muszą być chronione. Według Google Security Blog (2025), 67% podatności w aplikacjach mobilnych związanych jest z przechowywaniem sekretów w otwartej postaci.

Każda platforma mobilna udostępnia własne mechanizmy Secure Storage: Android — Keystore i EncryptedSharedPreferences, iOS — Keychain i Data Protection API. Mechanizmy te są zintegrowane ze sprzętowymi modułami bezpieczeństwa (TEE, Secure Enclave) i gwarantują, że dane nie mogą być odczytane nawet po jailbreaku lub rootowaniu urządzenia.

Właściwy wybór metody Secure Storage zależy od rodzaju danych, scenariusza użycia i wymagań dotyczących wydajności. Zrozumienie architektury każdego mechanizmu pozwala programiście podjąć właściwą decyzję architektoniczną.

Secure Storage na Androidzie

Platforma Android udostępnia kilka poziomów ochrony danych, od sprzętowego magazynu kluczy po zaszyfrowane SharedPreferences. Wybór zależy od wrażliwości danych i wymagań dotyczących wydajności.

Android Keystore — sprzętowe przechowywanie kluczy

Android Keystore — dostawca kryptograficzny generujący i przechowujący klucze w izolowanym środowisku wykonawczym (TEE — Trusted Execution Environment) na urządzeniach z obsługą ochrony sprzętowej. Klucze nigdy nie opuszczają TEE: operacje kryptograficzne są wykonywane wewnątrz chronionego obszaru, niedostępnego nawet dla systemu operacyjnego.

Od Androida 9 (API 28) Keystore obsługuje StrongBox Keymaster — dedykowany chip bezpieczeństwa z własnym CPU, True Random Number Generator (TRNG) i chronioną pamięcią. StrongBox jest certyfikowany zgodnie z Common Criteria EAL 4+ i stanowi najbezpieczniejszy poziom przechowywania kluczy na Androidzie. Aby użyć StrongBox, należy jawnie wskazać flagę inStrongBox() przy generowaniu klucza.

Keystore obsługuje algorytmy: AES/GCM/NoPadding (256 bitów), EC (secp256r1, secp384r1), RSA (2048–4096 bitów) i HMAC-SHA256. Wszystkie klucze mogą być powiązane z uwierzytelnianiem biometrycznym poprzez setUserAuthenticationRequired(true).

EncryptedSharedPreferences

EncryptedSharedPreferences — biblioteka z pakietu AndroidX Security, która automatycznie szyfruje wszystkie dane zapisywane przez API SharedPreferences. Wartości są szyfrowane kluczem AES-256 GCM, a klucze — AES-256 SIV (syntetyczny IV), co zapobiega atakom słownikowym na nazwy kluczy.

Główny klucz szyfrujący jest przechowywany w Android Keystore, zapewniając ochronę dwupoziomową: Keystore chroni klucz główny, EncryptedSharedPreferences chroni dane. Wydajność szyfrowania wynosi poniżej 5 ms na operację odczytu/zapisu dla typowych danych (token, ustawienia), co czyni bibliotekę odpowiednią do scenariuszy użytkownika.

EncryptedSharedPreferences nie jest przeznaczona do dużych ilości danych (powyżej 5 MB) — w takich przypadkach należy użyć zaszyfrowanej bazy danych przez SQLCipher lub Room z szyfrowaniem.

SQLCipher — zaszyfrowana baza danych

SQLCipher — rozszerzenie SQLite, które szyfruje całą bazę danych stronicowo z użyciem AES-256-CBC. Każda strona bazy danych jest szyfrowana oddzielnym kluczem pochodnym od hasła głównego przez PBKDF2. SQLCipher dodaje około 5–15% narzutu wydajnościowego w zależności od rozmiaru danych.

Integracja z Androidem odbywa się przez bibliotekę net.zetetic:android-database-sqlcipher, która udostępnia API zgodne ze standardowym SQLiteOpenHelper. Hasło do SQLCipher zaleca się przechowywać w Keystore, a nie w kodzie lub SharedPreferences.

Secure Storage na iOS

Platforma iOS udostępnia Keychain Services — główny bezpieczny magazyn, oraz Data Protection API do szyfrowania plików na poziomie systemu operacyjnego.

Keychain Services

Keychain — zaszyfrowana baza danych SQLite, w której iOS przechowuje hasła, klucze szyfrujące, certyfikaty i notatki. Każdy element Keychain (SecItem) jest przechowywany w zaszyfrowanej postaci z użyciem sprzętowego klucza unikalnego dla urządzenia. Dostęp do elementu jest kontrolowany przez ACL (Access Control List), który może wymagać uwierzytelniania biometrycznego (Face ID, Touch ID) lub kodu dostępu.

Keychain obsługuje klasy ochrony (Protection Class) określające, kiedy dane są dostępne: kSecAttrAccessibleWhenUnlockedThisDeviceOnly — dane dostępne tylko przy odblokowanym urządzeniu i nieprzenoszone podczas kopii zapasowej. Ta klasa jest zalecana dla większości scenariuszy przechowywania tokenów uwierzytelniających.

Na iOS 15+ dostępny jest Security framework z obsługą sprzętowych kluczy przez Secure Enclave — dedykowany procesor Apple, który przetwarza operacje kryptograficzne i przechowuje klucze prywatne w izolowanej pamięci. Secure Enclave obsługuje algorytmy ECDSA (secp256r1) i ECDH do generowania kluczy, których nie można wyodrębnić z chipa.

Data Protection API

Data Protection — mechanizm iOS szyfrujący każdy plik na poziomie systemu plików (APFS) z użyciem klucza powiązanego z kodem dostępu urządzenia. Deweloper określa poziom ochrony przez atrybut NSFileProtectionType przy tworzeniu pliku: NSFileProtectionComplete — plik dostępny tylko przy odblokowanym urządzeniu.

Data Protection działa automatycznie na wszystkich urządzeniach z iOS 5+, jeśli ustawiony jest kod dostępu. Szyfrowanie jest wykonywane na poziomie sprzętowym przez Dedicated AES Engine procesora Apple, co zapewnia wysoką wydajność — opóźnienie szyfrowania jest praktycznie niezauważalne dla użytkownika. Aby włączyć ochronę w aplikacji, wystarczy ustawić atrybut ochrony przy tworzeniu pliku przez FileManager.

Data Protection nie zastępuje Keychain do przechowywania kluczy — służy do szyfrowania plików, baz danych Core Data i innych dużych ilości danych. Kombinacja Keychain (dla kluczy) i Data Protection (dla plików) zapewnia pełny cykl bezpiecznego przechowywania na iOS.

Przykłady kodu: szyfrowanie danych na Androidzie i iOS

Rozważmy praktyczne przykłady Secure Storage z użyciem wbudowanych API Androida i iOS.

EncryptedSharedPreferences w Kotlin

Przykład pokazuje inicjalizację EncryptedSharedPreferences z kluczem głównym z Android Keystore. Wszystkie kolejne operacje odczytu i zapisu są automatycznie szyfrowane i deszyfrowane.

kotlin
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey

val masterKey = MasterKey.Builder(context)
    .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
    .build()

val prefs = EncryptedSharedPreferences.create(
    context,
    "secure_prefs",
    masterKey,
    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)

prefs.edit()
    .putString("auth_token", "eyJhbGciOiJIUzI1NiJ9...")
    .apply()

Keychain w Swift

Przykład demonstruje zapisywanie i odczytywanie danych z iOS Keychain z użyciem Security framework. Kod wykorzystuje kSecAttrAccessibleWhenUnlockedThisDeviceOnly dla maksymalnej ochrony.

swift
import Security

func saveToKeychain(key: String, data: Data) {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrAccount as String: key,
        kSecValueData as String: data,
        kSecAttrAccessible as String:
            kSecAttrAccessibleWhenUnlockedThisDeviceOnly
    ]
    SecItemDelete(query as CFDictionary)
    SecItemAdd(query as CFDictionary, nil)
}

func readFromKeychain(key: String) -> Data? {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrAccount as String: key,
        kSecReturnData as String: true,
        kSecMatchLimit as String: kSecMatchLimitOne
    ]
    var result: AnyObject?
    let status = SecItemCopyMatching(
        query as CFDictionary, &result
    )
    return status == errSecSuccess ? result as? Data : nil
}

SQLCipher w Kotlin

Przykład połączenia z zaszyfrowaną bazą SQLite przez SQLCipher z hasłem przechowywanym w Android Keystore.

kotlin
import net.sqlcipher.database.SQLiteDatabase
import net.sqlcipher.database.SQLiteOpenHelper

class SecureDBHelper(context: Context) :
    SQLiteOpenHelper(context, "secure.db", null, 1) {

    private val password = getKeyFromKeystore()

    override fun onCreate(db: SQLiteDatabase) {
        db.execSQL("CREATE TABLE tokens (id INTEGER PRIMARY KEY, value TEXT)")
    }

    override fun onUpgrade(
        db: SQLiteDatabase, oldVersion: Int, newVersion: Int
    ) {
        onCreate(db)
    }
}

// Użycie: podaj hasło przy otwieraniu
val helper = SecureDBHelper(context)
val db = helper.getWritableDatabase(password)

Zalecenia dotyczące bezpiecznego przechowywania danych

Prawidłowe użycie Secure Storage wymaga przestrzegania kilku fundamentalnych zasad, które zapobiegają typowym błędom programistów.

Określ klasyfikację danych: które dane wymagają ochrony sprzętowej (Keystore / Secure Enclave), które — szyfrowania na poziomie systemu operacyjnego (EncryptedSharedPreferences / Data Protection), a które można przechowywać w zwykłym systemie plików. Tokeny uwierzytelniające, klucze prywatne i dane płatnicze — tylko poziom sprzętowy. Ustawienia użytkownika (motyw, język) — wystarczy EncryptedSharedPreferences. Dane sesji (tymczasowe pamięci podręczne) mogą być przechowywane w pamięci lub katalogu tymczasowym.

Nigdy nie przechowuj sekretów w kodzie: ciągi z kluczami API, hasłami lub frazami seed w kodzie źródłowym to najpoważniejszy błąd bezpieczeństwa. Każdy reverse engineering natychmiast ujawni te dane. Używaj Keystore dla kluczy, a do konfiguracji — zdalne ładowanie przy uruchomieniu aplikacji (remote config).

Używaj powiązania biometrycznego dla krytycznych operacji: Android Keystore i iOS Keychain obsługują powiązanie kluczy z uwierzytelnianiem biometrycznym. Przy każdym dostępie do klucza system prosi o Face ID, Touch ID lub biometrię Androida (BiometricPrompt). Gwarantuje to, że nawet przy pełnej kontroli nad urządzeniem atakujący nie będzie mógł użyć zapisanych danych bez właściciela.

Testuj ochronę: używaj narzędzi analizy bezpieczeństwa — MobSF (Mobile Security Framework) do analizy statycznej, objection do testów runtime i Frida do omijania zabezpieczeń. Sprawdzaj, czy dane są niedostępne po rootowaniu lub jailbreaku. Android umożliwia sprawdzenie obecności roota przez SafetyNet Attestation lub Play Integrity API, iOS — przez weryfikację integralności Secure Enclave.

Regularnie aktualizuj biblioteki kryptograficzne: podatności w bibliotekach szyfrujących są wykrywane regularnie. Śledź CVE dla AndroidX Security, SQLCipher i wrapperów Keychain. Wdróż system automatycznych powiadomień o nowych wersjach przez Dependabot lub Renovate.

Według Apple Security Research (2025), prawidłowa implementacja Secure Storage zapobiega 96% ataków mających na celu kradzież danych z urządzenia. Pozostałe 4% — ataki z fizycznym dostępem i exploity dnia zerowego, przeciwko którym skuteczne jest powiązanie biometryczne.

Często zadawane pytania

Jaka jest różnica między Keychain a Keystore?

iOS Keychain — zaszyfrowana baza danych do przechowywania haseł, kluczy i certyfikatów z kontrolą dostępu przez ACL. Android Keystore — dostawca kryptograficzny generujący i przechowujący klucze w izolowanym środowisku (TEE/StrongBox), który nie pozwala na wyodrębnienie klucza prywatnego.

Jaki algorytm szyfrowania jest używany w EncryptedSharedPreferences?

EncryptedSharedPreferences używa AES-256 GCM do szyfrowania wartości i AES-256 SIV do szyfrowania kluczy. Główny klucz jest przechowywany w Android Keystore, zapewniając ochronę dwupoziomową. Dodatkowo używany jest HMAC-SHA256 do weryfikacji integralności.

Czy trzeba szyfrować dane już chronione przez HTTPS?

Tak, HTTPS chroni dane tylko w kanale transmisji. Na urządzeniu dane są przechowywane w otwartej postaci po deszyfrowaniu. Jeśli atakujący uzyska fizyczny dostęp do urządzenia lub zainstaluje złośliwe oprogramowanie, HTTPS nie ochroni zapisanych danych. Zawsze szyfruj dane na poziomie przechowywania.

Jak chronić dane po rootowaniu Androida?

Użyj Android Keystore z flagą setUnlockedDeviceRequired(true), która blokuje dostęp do kluczy na zrootowanych urządzeniach. Dodatkowo sprawdzaj integralność przez Play Integrity API, a w przypadku odchyleń od wartości referencyjnych czyść wszystkie sekrety z magazynu.

Czy można używać UserDefaults do przechowywania tokenów na iOS?

Nie, UserDefaults przechowuje dane w otwartej postaci w pliku plist w piaskownicy. Każda aplikacja z narzędziami reverse engineeringu (przez kopię zapasową lub jailbreak) może odczytać tokeny. Tylko Keychain — jedyne bezpieczne miejsce do przechowywania sekretów na iOS.

Podsumowanie

  • Secure Storage — obowiązkowy komponent ochrony aplikacji mobilnych zapobiegający wyciekowi danych przy fizycznym dostępie do urządzenia.
  • Android Keystore z StrongBox zapewnia sprzętowe przechowywanie kluczy na dedykowanym chipie bezpieczeństwa.
  • iOS Keychain z klasami ochrony (WhenUnlockedThisDeviceOnly) — standard przechowywania sekretów na platformie Apple.
  • EncryptedSharedPreferences — gotowe rozwiązanie do szyfrowania ustawień i tokenów na Androidzie z dwupoziomową kryptografią.
  • SQLCipher — wybór dla zaszyfrowanych baz danych z szyfrowaniem stronicowym AES-256-CBC.
  • Data Protection na iOS i SafetyNet/Play Integrity na Androidzie — dodatkowe poziomy ochrony systemu plików.
  • Prawidłowa klasyfikacja danych i powiązanie biometryczne zapobiegają 96% ataków na przechowywane dane według Apple Security Research.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również