Bezpieczeństwo mobilne to zestaw środków ochrony aplikacji, danych użytkownika i infrastruktury serwerowej przed atakami i wyciekami. Według OWASP Mobile Top 10 (2024), niebezpieczne przechowywanie danych pozostaje najczęstszą luką w aplikacjach mobilnych. W tym artykule omówimy główne zagrożenia, metody szyfrowania, bezpieczne przechowywanie, uwierzytelnianie i ochronę kodu — wszystko, co początkujący programista musi wiedzieć.
Najważniejsze Wnioski
OWASP (Open Web Application Security Project) to organizacja non-profit publikująca ranking najniebezpieczniejszych luk w bezpieczeństwie mobilnym. OWASP Mobile Top 10 to lista, która pomaga programistom zrozumieć, na czym skupić się w pierwszej kolejności. W wersji 2024 na czele rankingu znajdują się problemy związane z niebezpiecznym przechowywaniem, słabym uwierzytelnianiem i niebezpieczną komunikacją sieciową.
M1: Niebezpieczne Przechowywanie Danych — najczęstszy problem: hasła, tokeny i dane osobowe pozostają w SharedPreferences, NSUserDefaults lub plikach lokalnych bez szyfrowania. M2: Słabe Uwierzytelnianie — brak weryfikacji po stronie serwera, słabe hasła. M3: Niebezpieczna Komunikacja Sieciowa — brak HTTPS lub nieprawidłowa weryfikacja certyfikatu SSL. M4 i M5 są związane z kryptografią i nieprawidłowym użyciem API.
M6: Niebezpieczna Autoryzacja — użytkownik może uzyskać dostęp do danych innego użytkownika poprzez podmianę identyfikatora w żądaniu. M7: Iniekcja Kodu (SQL Injection, XSS). M8: Manipulacja Aplikacją — repackaging, podmiana kodu. M9 i M10 — wyciek danych przez biblioteki stron trzecich i inżynieria wsteczna. Dla każdego z tych zagrożeń istnieją sprawdzone środki zaradcze, a w IT Sectr stosujemy je we wszystkich projektach od 2017 roku.
Atak MITM ma miejsce, gdy osoba atakująca przechwytuje ruch między aplikacją a serwerem. Jest to możliwe poprzez fałszowanie DNS, ARP spoofing lub połączenie z niezabezpieczoną siecią Wi-Fi. Do ochrony używane są certyfikaty SSL/TLS i Certificate Pinning.
Certificate Pinning to mechanizm, w którym aplikacja sprawdza, czy certyfikat serwera jest zgodny z wcześniej zapisanym w kodzie aplikacji. Nawet jeśli osoba atakująca podmieni certyfikat przez proxy (np. Burp Suite), aplikacja odrzuci połączenie. Pinning występuje w dwóch rodzajach: Public Key Pinning i Certificate Hash Pinning.
AES (Advanced Encryption Standard) to algorytm szyfrowania symetrycznego, podstawa bezpieczeństwa danych na urządzeniu. AES używa tego samego klucza do szyfrowania i deszyfrowania danych. AES obsługuje klucze o długości 128, 192 lub 256 bitów. W rozwoju mobilnym AES-256 jest używany do szyfrowania danych na urządzeniu: plików, pamięci podręcznej, rekordów w lokalnej bazie danych.
Tryby AES: GCM (zalecany) — zapewnia uwierzytelnianie danych, CBC — tryb podstawowy z łączeniem bloków, ECB — niebezpieczny, nie używaj go. Dla iOS AES jest dostępny przez CommonCrypto (CCOptions), dla Androida — przez Cipher w Java Cryptography Architecture (JCA). Ważne: klucz szyfrowania nigdy nie powinien być przechowywany w kodzie aplikacji — używaj Keychain/Keystore.
Szyfrowanie Asymetryczne: RSA — używa pary kluczy (publicznego i prywatnego). RSA jest używane do szyfrowania małych ilości danych — zazwyczaj do wymiany klucza symetrycznego między klientem a serwerem. Minimalna długość klucza RSA to 2048 bitów (zalecane 4096). Na iOS RSA jest dostępne przez Security Framework (SecKeyCreateRandomKey), na Androidzie — przez KeyPairGenerator w Android Keystore.
Haszowanie (SHA-256, SHA-3) to nieodwracalna transformacja danych w ciąg o stałej długości. Hasze są używane do weryfikacji integralności danych i przechowywania haseł. Do haseł obowiązkowo używaj bcrypt, scrypt lub Argon2 — zwykły SHA-256 jest podatny na ataki z użyciem tablic rainbow. SSL/TLS to protokół szyfrowania ruchu sieciowego między klientem a serwerem. Nowoczesnym standardem jest TLS 1.3, który zapewnia Perfect Forward Secrecy (PFS).
TLS 1.3 jest szybszy od swoich poprzedników: uzgadnianie (handshake) zajmuje jedną rundę zamiast dwóch. Na Androidzie minimalna wersja TLS jest konfigurowana przez SSLSocket, na iOS — przez ATS (App Transport Security), który domyślnie wymaga TLS 1.2 lub wyższego. ATS można wyłączyć tylko dla konkretnych domen z uzasadnieniem.
Keychain (Brełok) to bezpieczne przechowywanie w iOS / macOS dla haseł, kluczy szyfrowania, certyfikatów i tokenów. Dane w Keychain są szyfrowane sprzętowym kluczem unikalnym dla każdego urządzenia. Dostęp do Keychain jest kontrolowany przez Security Framework (SecItemAdd, SecItemCopyMatching). Keychain automatycznie blokuje się po zablokowaniu urządzenia i jest szyfrowany za pomocą Secure Enclave.
Android Keystore to systemowe przechowywanie kluczy kryptograficznych, odizolowane od aplikacji. Od Androida 6.0 (API 23) Keystore korzysta ze wsparcia sprzętowego (TEE — Trusted Execution Environment) na urządzeniach z układem zabezpieczeń. Klucze w Keystore nigdy nie opuszczają bezpiecznego obszaru — aplikacja otrzymuje tylko uchwyt do operacji szyfrowania i podpisywania.
| Parametr | iOS Keychain | Android Keystore |
|---|---|---|
| Rodzaj przechowywanych danych | Hasła, tokeny, klucze, certyfikaty | Klucze kryptograficzne |
| Wsparcie sprzętowe | Secure Enclave (wszystkie iPhone z A7+) | TEE (Android 6+, zależy od układu) |
| Szyfrowanie | AES-256 sprzętowe | AES/GCM z kluczem sprzętowym |
| Biometria | Face ID / Touch ID do dostępu | BiometricPrompt do dostępu |
| iCloud / kopia zapasowa | Synchronizacja przez iCloud Keychain | Nie synchronizuje się z chmurą |
| Wydajność | Wolniejsze (sprzętowe szyfrowanie) | Szybsze (TEE) |
SharedPreferences i NSUserDefaults nie są przeznaczone do przechowywania poufnych danych — przechowują informacje w postaci jawnej. Do ochrony danych używaj EncryptedSharedPreferences (Android) lub szyfruj dane przed zapisaniem w UserDefaults (iOS). W IT Sectr zawsze używamy Keychain i Keystore do tokenów dostępu i haseł.
OAuth 2.0 to protokół delegowanej autoryzacji, który zapewnia bezpieczny dostęp do zasobów użytkownika bez przesyłania hasła. W aplikacjach mobilnych najczęściej używany jest Authorization Code Flow z PKCE (Proof Key for Code Exchange). PKCE zapobiega przechwyceniu kodu autoryzacyjnego — obowiązkowy wymóg dla aplikacji mobilnych.
OpenID Connect (OIDC) to rozszerzenie na bazie OAuth 2.0 do uwierzytelniania użytkownika. OIDC dodaje ID Token w formacie JWT, który zawiera informacje o użytkowniku (nazwa, email, id). Przepływ OAuth 2.0 + OIDC obejmuje: przekierowanie użytkownika na stronę logowania, uzyskanie kodu autoryzacyjnego, wymianę kodu na tokeny (access + refresh + id), użycie tokena dostępu do żądań API.
JWT (JSON Web Token) to kompaktowy, bezpieczny dla URL format tokena zawierający dane (claims) w formacie JSON. JWT składa się z trzech części: nagłówka (typ i algorytm podpisu), ładunku (dane) i podpisu. Token Dostępu to krótkożyjący token (15–60 minut) do dostępu do API. Token Odświeżania to długożyjący token (dni/tygodnie) do uzyskania nowego tokena dostępu bez ponownego logowania.
Token Sesji to tradycyjne podejście, w którym serwer przechowuje sesję w bazie danych lub Redis, a klient otrzymuje losowy identyfikator. W rozwoju mobilnym preferowany jest JWT: nie wymaga przechowywania sesji po stronie serwera, zawiera wszystkie informacje wewnątrz siebie i jest łatwy do weryfikacji. Jednak JWT nie może być natychmiast unieważniony — to kompromis, który jest rozwiązywany przez krótki czas życia tokena dostępu i użycie tokenów odświeżania.
Face ID i Touch ID na iOS, Uwierzytelnianie Odciskami Palców na Androidzie — biometryczne metody uwierzytelniania wykorzystujące unikalne cechy fizyczne użytkownika. Na iOS biometria działa przez LocalAuthentication (LAContext), na Androidzie — przez BiometricPrompt (Android 9+) lub FingerprintManager (przestarzały). Biometria jest używana do odblokowywania aplikacji, potwierdzania płatności i dostępu do chronionych danych.
Ważne niuanse: biometria to wygodny UX, ale nie zastępuje uwierzytelniania serwerowego. Po pomyślnej weryfikacji biometrycznej aplikacja powinna uzyskać token dostępu z serwera. Na Androidzie koniecznie sprawdź, czy urządzenie używa biometrii Klasy 3 (Silnej), a nie tylko rozpoznawania twarzy za pomocą kamery (Klasa 1).
ProGuard to narzędzie do obfuskacji, kompresji i optymalizacji kodu bajtowego Java dla Androida, zwiększające bezpieczeństwo kodu przed inżynierią wsteczną. R8 jest jego następcą, wbudowanym w Gradle od Android Studio 3.4. R8 wykonuje cztery zadania: kompresję (usuwa nieużywane klasy i metody), optymalizację (inline'uje metody, upraszcza kod), obfuskację (zmienia nazwy klas i metod na krótkie) i pre-weryfikację (sprawdzanie kodu bajtowego).
DexGuard to komercyjna wersja ProGuard z rozszerzoną ochroną: szyfrowanie stringów, obfuskacja zasobów, ochrona przed repackagingiem, kontrola integralności APK. Do większości projektów wystarcza R8, ale dla aplikacji finansowych i bankowych DexGuard zapewnia dodatkową warstwę bezpieczeństwa. R8 włącza się przez build.gradle: minifyEnabled = true i proguardFiles.
Root Detection (Android) i Jailbreak Detection (iOS) to mechanizmy sprawdzające, czy na urządzeniu uzyskano uprawnienia superużytkownika. Na zhakowanych urządzeniach można czytać pamięć procesu, przechwytywać ruch i podmieniać kod. Do sprawdzenia na Androidzie używa się obecności pliku binarnego SU, testowych kluczy podpisu i niestandardowych flag kompilacji.
RASP (Runtime Application Self-Protection) to technologia chroniąca aplikację podczas wykonywania. RASP wykrywa próby debugowania, repackagingu, iniekcji kodu i zamyka aplikację po wykryciu zagrożeń. Przykłady rozwiązań RASP: Dexter, Guardsquare, Promon. RASP działa w czasie wykonywania i reaguje na anomalie — w przeciwieństwie do statycznej obfuskacji, która chroni kod przed wykonaniem.
Inżynieria Wsteczna to proces odzyskiwania kodu źródłowego ze skompilowanej aplikacji. Narzędzia: JADX (dekompilator APK), Ghidra, IDA Pro, Hopper. Ochrona przed Inżynierią Wsteczną to kombinacja obfuskacji, szyfrowania stringów, sprawdzania integralności i Root Detection. Pełna ochrona nie istnieje — celem jest uczynienie inżynierii wstecznej wystarczająco kosztowną dla atakującego.
Często Zadawane Pytania
Zacznij od OWASP Mobile Top 10 — to mapa drogowa najczęstszych luk. Następnie przestudiuj HTTPS i certyfikaty SSL, skonfiguruj Certificate Pinning i przejdź do bezpiecznego przechowywania przez Keychain / Keystore.
AES (symetryczne) — jeden klucz do szyfrowania i deszyfrowania, szybki, odpowiedni dla dużych ilości danych. RSA (asymetryczne) — para kluczy (publiczny i prywatny), wolniejszy, używany do wymiany klucza symetrycznego.
Należy szyfrować tylko dane poufne: hasła, tokeny, dane osobowe użytkownika, informacje płatnicze. Obrazy, teksty i ustawienia interfejsu nie wymagają szyfrowania — to zwiększyłoby rozmiar i spowolniło aplikację.
Refresh Token to długożyjący token, który umożliwia uzyskanie nowego Access Tokena bez ponownego wprowadzania hasła. Zwiększa to bezpieczeństwo — Access Token żyje 15–60 minut, a nawet jeśli wycieknie, atakujący nie może go długo używać.
Tak, R8 musi być włączony dla wydań produkcyjnych Androida. To nie tylko ochrona przed Inżynierią Wsteczną, ale także zmniejszenie rozmiaru APK i optymalizacja wydajności. Bez R8 Twój kod można zdekompilować do czytelnej postaci jednym poleceniem JADX.
Podsumowanie
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.