Bootstrap

Android开发实战班 - 数据持久化 - 数据加密与安全

在 Android 应用开发中,数据安全至关重要,尤其是在处理敏感信息(如用户密码、支付信息、个人隐私数据等)时。数据加密是保护数据安全的重要手段,可以有效防止数据泄露、篡改和未经授权的访问。本章节将介绍 Android 开发中常用的数据加密方法、加密库的使用、安全存储方案以及最佳实践,帮助学员掌握数据加密与安全的实现。

  • 什么是数据加密:

    • 数据加密是指将明文数据通过加密算法转换为密文数据,只有持有正确密钥的人才能解密并读取数据。
  • 数据加密的目的:

    • 保密性: 防止数据泄露,确保只有授权用户才能读取数据。
    • 完整性: 防止数据被篡改,确保数据的完整性和一致性。
    • 身份验证: 验证数据的来源,确保数据来自可信的发送者。
  • 加密类型:

    • 对称加密: 使用相同的密钥进行加密和解密,例如 AES。
    • 非对称加密: 使用一对公钥和私钥进行加密和解密,例如 RSA。
    • 哈希加密: 将数据转换为固定长度的哈希值,例如 SHA-256。

18.2 常用加密算法

18.2.1 对称加密
  • AES (Advanced Encryption Standard):

    • 高级加密标准,是目前最常用的对称加密算法。
    • 密钥长度可以是 128、192 或 256 位。
    • 适用于加密大量数据,加密和解密速度快。
    import javax.crypto.Cipher
    import javax.crypto.KeyGenerator
    import javax.crypto.SecretKey
    import javax.crypto.spec.SecretKeySpec
    
    // 生成 AES 密钥
    fun generateAesKey(): SecretKey {
        val keyGenerator = KeyGenerator.getInstance("AES")
        keyGenerator.init(256)
        return keyGenerator.generateKey()
    }
    
    // AES 加密
    fun encryptAes(data: ByteArray, key: SecretKey): ByteArray {
        val cipher = Cipher.getInstance("AES")
        cipher.init(Cipher.ENCRYPT_MODE, key)
        return cipher.doFinal(data)
    }
    
    // AES 解密
    fun decryptAes(encryptedData: ByteArray, key: SecretKey): ByteArray {
        val cipher = Cipher.getInstance("AES")
        cipher.init(Cipher.DECRYPT_MODE, key)
        return cipher.doFinal(encryptedData)
    }
    
18.2.2 非对称加密
  • RSA (Rivest–Shamir–Adleman):

    • RSA 是一种常用的非对称加密算法。
    • 使用一对公钥和私钥进行加密和解密。
    • 适用于加密少量数据,例如加密对称密钥。
    import java.security.KeyPairGenerator
    import java.security.PrivateKey
    import java.security.PublicKey
    import javax.crypto.Cipher
    
    // 生成 RSA 密钥对
    fun generateRsaKeyPair(): KeyPair {
        val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
        keyPairGenerator.initialize(2048)
        return keyPairGenerator.generateKeyPair()
    }
    
    // RSA 加密
    fun encryptRsa(data: ByteArray, publicKey: PublicKey): ByteArray {
        val cipher = Cipher.getInstance("RSA")
        cipher.init(Cipher.ENCRYPT_MODE, publicKey)
        return cipher.doFinal(data)
    }
    
    // RSA 解密
    fun decryptRsa(encryptedData: ByteArray, privateKey: PrivateKey): ByteArray {
        val cipher = Cipher.getInstance("RSA")
        cipher.init(Cipher.DECRYPT_MODE, privateKey)
        return cipher.doFinal(encryptedData)
    }
    
18.2.3 哈希加密
  • SHA-256 (Secure Hash Algorithm 256):

    • SHA-256 是一种常用的哈希加密算法。
    • 将任意长度的数据转换为 256 位的哈希值。
    • 适用于数据完整性校验和密码存储。
    import java.security.MessageDigest
    
    // SHA-256 哈希
    fun sha256(data: String): String {
        val md = MessageDigest.getInstance("SHA-256")
        val hashBytes = md.digest(data.toByteArray())
        return hashBytes.joinToString("") { "%02x".format(it) }
    }
    

18.3 Android 中的安全存储

  • Keystore 系统:

    • Android 提供了 Keystore 系统,用于安全地存储和管理密钥。
    • Keystore 可以生成密钥,并提供安全的密钥存储和加密操作。
    • 密钥存储在设备的硬件安全模块中,无法被提取。
    import android.security.keystore.KeyGenParameterSpec
    import android.security.keystore.KeyProperties
    import java.security.KeyStore
    
    // 生成 Keystore 密钥
    fun generateKeystoreKey(alias: String) {
        val keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
        val keyGenParameterSpec = KeyGenParameterSpec.Builder(
            alias,
            KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
        )
            .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
            .setKeySize(256)
            .build()
        keyGenerator.init(keyGenParameterSpec)
        keyGenerator.generateKey()
    }
    
    // 获取 Keystore 密钥
    fun getKeystoreKey(alias: String): SecretKey {
        val keyStore = KeyStore.getInstance("AndroidKeyStore")
        keyStore.load(null)
        return keyStore.getKey(alias, null) as SecretKey
    }
    
  • EncryptedFile 和 EncryptedSharedPreferences:

    • Android Jetpack 提供了 EncryptedFileEncryptedSharedPreferences,用于加密文件和数据存储。
    • EncryptedFile 可以对文件进行加密和解密。
    • EncryptedSharedPreferences 可以在 SharedPreferences 中存储加密数据。
    import androidx.security.crypto.EncryptedFile
    import androidx.security.crypto.EncryptedSharedPreferences
    import androidx.security.crypto.MasterKeys
    
    // 使用 EncryptedFile 加密文件
    fun writeEncryptedFile(context: Context, fileName: String, content: String) {
        val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES_256_GCM_SPEC)
        val file = File(context.filesDir, fileName)
        val encryptedFile = EncryptedFile.Builder(
            file,
            context,
            masterKeyAlias,
            EncryptedFile.FileEncryptionScheme.AES256_SIV
        ).build()
    
        encryptedFile.openFileOutput().bufferedWriter().use { writer ->
            writer.write(content)
        }
    }
    
    // 使用 EncryptedSharedPreferences 加密 SharedPreferences
    fun getEncryptedSharedPreferences(context: Context): SharedPreferences {
        val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES_256_GCM_SPEC)
        return EncryptedSharedPreferences.create(
            "secret_shared_prefs",
            masterKeyAlias,
            context,
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
        )
    }
    

18.4 数据加密最佳实践

  • 使用强加密算法:

    • 使用经过验证的强加密算法,例如 AES, RSA, SHA-256 等。
  • 保护密钥:

    • 密钥是加密安全的核心,必须妥善保护。
    • 使用 Android Keystore 系统存储和管理密钥,避免密钥泄露。
  • 最小权限原则:

    • 只存储和传输必要的数据,避免存储敏感信息。
    • 最小化权限申请,只申请应用所需的最低权限。
  • 安全存储:

    • 使用加密存储方案,例如 EncryptedFile, EncryptedSharedPreferences 等。
    • 避免在代码中硬编码密钥或敏感信息。
  • 数据备份:

    • 对敏感数据进行加密备份,避免备份数据泄露。
  • 错误处理:

    • 妥善处理加密操作中的异常,避免敏感信息泄露。
;