askill
mobile-security

mobile-securitySafety 88Repository

Android security patterns for secure storage, network security, input validation, and authentication.

27 stars
1.2k downloads
Updated 2/4/2026

Package Files

Loading files...
SKILL.md

Mobile Security Patterns

Security best practices for Android.

Secure Storage

EncryptedSharedPreferences

// Create encrypted preferences
private fun createSecurePrefs(context: Context): SharedPreferences {
    val masterKey = MasterKey.Builder(context)
        .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
        .build()
    
    return EncryptedSharedPreferences.create(
        context,
        "secure_prefs",
        masterKey,
        EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
        EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
    )
}

// Usage
class TokenStorage(context: Context) {
    private val prefs = createSecurePrefs(context)
    
    var accessToken: String?
        get() = prefs.getString("access_token", null)
        set(value) = prefs.edit().putString("access_token", value).apply()
    
    fun clear() = prefs.edit().clear().apply()
}

Android Keystore

// Generate key in Keystore
fun generateSecretKey(alias: String) {
    val keyGenerator = KeyGenerator.getInstance(
        KeyProperties.KEY_ALGORITHM_AES,
        "AndroidKeyStore"
    )
    
    keyGenerator.init(
        KeyGenParameterSpec.Builder(alias,
            KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
            .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
            .setUserAuthenticationRequired(true)
            .setUserAuthenticationParameters(300, KeyProperties.AUTH_BIOMETRIC_STRONG)
            .build()
    )
    
    keyGenerator.generateKey()
}

Network Security

Network Security Config

<!-- res/xml/network_security_config.xml -->
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="false">
        <trust-anchors>
            <certificates src="system"/>
        </trust-anchors>
    </base-config>
    
    <!-- Debug only -->
    <debug-overrides>
        <trust-anchors>
            <certificates src="user"/>
        </trust-anchors>
    </debug-overrides>
    
    <!-- Certificate pinning -->
    <domain-config>
        <domain includeSubdomains="true">api.example.com</domain>
        <pin-set expiration="2025-12-31">
            <pin digest="SHA-256">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</pin>
            <pin digest="SHA-256">BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=</pin>
        </pin-set>
    </domain-config>
</network-security-config>

Certificate Pinning (Ktor)

val client = HttpClient(OkHttp) {
    engine {
        config {
            certificatePinner(
                CertificatePinner.Builder()
                    .add("api.example.com", "sha256/AAAA...")
                    .add("api.example.com", "sha256/BBBB...")  // Backup
                    .build()
            )
        }
    }
}

Safe Logging

// ❌ NEVER log sensitive data
Log.d("Auth", "Token: $token")

// ✅ Release-safe logging with Timber
class ReleaseTree : Timber.Tree() {
    override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
        if (priority >= Log.WARN) {
            // Send to crash reporting
            Crashlytics.log(priority, tag, message)
        }
    }
}

// In Application
if (BuildConfig.DEBUG) {
    Timber.plant(Timber.DebugTree())
} else {
    Timber.plant(ReleaseTree())
}

Input Validation

// Validate before use
fun validateEmail(email: String): Result<String> {
    return when {
        email.isBlank() -> Result.failure(ValidationError.Empty)
        !Patterns.EMAIL_ADDRESS.matcher(email).matches() -> 
            Result.failure(ValidationError.InvalidFormat)
        email.length > 254 -> Result.failure(ValidationError.TooLong)
        else -> Result.success(email)
    }
}

// SQL injection prevention - use parameterized queries
@Query("SELECT * FROM users WHERE id = :userId")
suspend fun getUser(userId: String): User?

Biometric Authentication

val biometricPrompt = BiometricPrompt(
    activity,
    executor,
    object : BiometricPrompt.AuthenticationCallback() {
        override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
            val cipher = result.cryptoObject?.cipher
            // Use cipher to decrypt sensitive data
        }
    }
)

val promptInfo = BiometricPrompt.PromptInfo.Builder()
    .setTitle("Authenticate")
    .setNegativeButtonText("Cancel")
    .setAllowedAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG)
    .build()

biometricPrompt.authenticate(promptInfo, BiometricPrompt.CryptoObject(cipher))

ProGuard/R8 Security

# R8 rules for security
-keepattributes SourceFile,LineNumberTable  # For crash reports only

# Obfuscate sensitive classes
-repackageclasses 'a'
-allowaccessmodification

# Remove logging
-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
    public static *** i(...);
}

Remember: Security is not optional. Build it in from the start.

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

74/100Analyzed 2/24/2026

Good technical reference for Android security patterns with practical code examples. Covers key areas like encrypted storage, network security, and biometric auth. Lacks an introduction explaining when to use these patterns, and some tags seem mismatched. The structured code examples make it actionable, though it's more of a reference than a step-by-step guide.

88
75
85
65
72

Metadata

Licenseunknown
Version-
Updated2/4/2026
Publisherahmed3elshaer

Tags

apici-cddatabaseobservabilitysecurity