API Key Security
Relevant source files
The following files were used as context for generating this wiki page:
- app/src/main/kotlin/com/shadowcheck/mobile/utils/SecureApiKeyManager.kt
- app/src/main/kotlin/com/shadowcheck/mobile/ui/screens/settings/APIKeysScreen.kt
- app/src/main/kotlin/com/shadowcheck/mobile/rebuilt/ui/screens/SettingsScreen.kt
- app/src/main/kotlin/com/shadowcheck/mobile/network/dto/WigleApiService.kt
- app/src/main/kotlin/com/shadowcheck/mobile/data/Entities.kt
- app/src/main/AndroidManifest.xml
API Key Security in ShadowCheck Mobile refers to the comprehensive system used to manage, encrypt, and utilize sensitive credentials for external services such as WiGLE, Mapbox, and Google Maps. The application ensures that these keys are never stored in plain text on the device, utilizing hardware-backed encryption provided by the AndroidX Security library.
The scope of this system covers the entire lifecycle of an API key, including user input through secure UI components, encrypted persistence in EncryptedSharedPreferences, and secure injection into network services for authenticated API requests.
Sources: README.md, app/src/main/kotlin/com/shadowcheck/mobile/utils/SecureApiKeyManager.kt, app/src/main/kotlin/com/shadowcheck/mobile/ui/screens/settings/APIKeysScreen.kt
Architecture and Storage Logic
The security architecture relies on the SecureApiKeyManager, which acts as a centralized utility for all sensitive credential operations. It leverages the Android Keystore system via MasterKey and EncryptedSharedPreferences to ensure data-at-rest encryption.
Encryption Implementation
The system uses AES256-GCM for value encryption and AES256-SIV for key encryption. This ensures that even if the application's private storage is accessed, the contents remain unreadable without the hardware-backed master key.
The diagram above illustrates the flow of sensitive data from the user interface to the encrypted storage layer.
Sources: app/src/main/kotlin/com/shadowcheck/mobile/utils/SecureApiKeyManager.kt:14-25, app/src/main/kotlin/com/shadowcheck/mobile/rebuilt/ui/screens/SettingsScreen.kt:333-345
Storage Components
The application maintains two distinct encrypted preference files:
shadowcheck_api_keys: Managed bySecureApiKeyManagerfor general API key storage.secure_prefs: Managed within theSettingsScreenfor application-specific secure settings.
Sources: app/src/main/kotlin/com/shadowcheck/mobile/utils/SecureApiKeyManager.kt:18, app/src/main/kotlin/com/shadowcheck/mobile/rebuilt/ui/screens/SettingsScreen.kt:340
Key Management Interface
The user interface provides secure fields for entering and managing credentials. These fields include visual transformation logic to mask sensitive characters by default.
Secure UI Components
The ApiKeyField and APIKeysScreen implement several security best practices:
- Password Transformation: Uses
PasswordVisualTransformationto hide keys. - Visibility Toggling: Allows users to temporarily view the key for verification.
- Validation: The save button is only enabled when required fields (like WiGLE Name and Token) are populated.
The sequence diagram shows the interaction between the user interface and the secure management logic during key entry.
Sources: app/src/main/kotlin/com/shadowcheck/mobile/ui/screens/settings/APIKeysScreen.kt:25-85, app/src/main/kotlin/com/shadowcheck/mobile/rebuilt/ui/screens/SettingsScreen.kt:302-325
Network Integration and Authentication
Once stored securely, API keys are retrieved and injected into network requests. The WigleApiService uses an OkHttp interceptor to apply these credentials to every outgoing request via Basic Authentication.
Wigle Authentication Flow
The service accepts an apiName and apiToken, which are converted into a Base64 encoded Basic Auth header.
| Parameter | Source File | Description |
|---|---|---|
apiName | WigleApiService.kt | The username provided by WiGLE for API access. |
apiToken | WigleApiService.kt | The secret token provided by WiGLE. |
Authorization | WigleApiService.kt | Header generated using Credentials.basic(apiName, apiToken). |
Sources: app/src/main/kotlin/com/shadowcheck/mobile/network/dto/WigleApiService.kt:19-27
Implementation Detail: Network Interceptor
private val client = OkHttpClient.Builder()
.addInterceptor { chain ->
val request = chain.request().newBuilder()
.addHeader("Authorization", Credentials.basic(apiName, apiToken))
.build()
chain.proceed(request)
}
.build()
Sources: app/src/main/kotlin/com/shadowcheck/mobile/network/dto/WigleApiService.kt:19-25
Database Entity Mapping
The application defines specific Room entities to track API usage and metadata. This allows the system to monitor request counts and expiration dates without storing the actual keys in the main SQLite database.
API Security Entities
| Entity | Fields | Purpose |
|---|---|---|
ApiToken | service, token, expiresAt | Tracks token metadata and expiration. |
ApiUsage | service, endpoint, requestCount | Monitors volume of requests to prevent rate limiting. |
Sources: app/src/main/kotlin/com/shadowcheck/mobile/data/Entities.kt:145-163
Secure Management Operations
SecureApiKeyManager provides a singleton object for consistent key lifecycle management across the app.
Core Functions
| Function | Parameters | Description |
|---|---|---|
saveApiKey | Context, Name, Value | Encrypts and persists a new key. |
getApiKey | Context, Name | Decrypts and retrieves an existing key. |
deleteApiKey | Context, Name | Removes a key from secure storage. |
clearAll | Context | Wipes all stored keys (e.g., during a factory reset). |
Sources: app/src/main/kotlin/com/shadowcheck/mobile/utils/SecureApiKeyManager.kt:30-55
Conclusion
The API Key Security system in ShadowCheck Mobile provides a robust defense-in-depth approach to credential management. By combining hardware-backed encryption via the AndroidX Security library with secure UI practices and automated network authentication interceptors, the application ensures that external service credentials remain protected from both physical access and insecure handling within the application logic.
Sources: app/src/main/kotlin/com/shadowcheck/mobile/utils/SecureApiKeyManager.kt, app/src/main/kotlin/com/shadowcheck/mobile/network/dto/WigleApiService.kt, app/src/main/kotlin/com/shadowcheck/mobile/ui/screens/settings/APIKeysScreen.kt