在 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 提供了
EncryptedFile
和EncryptedSharedPreferences
,用于加密文件和数据存储。 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 ) }
- Android Jetpack 提供了
18.4 数据加密最佳实践
-
使用强加密算法:
- 使用经过验证的强加密算法,例如 AES, RSA, SHA-256 等。
-
保护密钥:
- 密钥是加密安全的核心,必须妥善保护。
- 使用 Android Keystore 系统存储和管理密钥,避免密钥泄露。
-
最小权限原则:
- 只存储和传输必要的数据,避免存储敏感信息。
- 最小化权限申请,只申请应用所需的最低权限。
-
安全存储:
- 使用加密存储方案,例如 EncryptedFile, EncryptedSharedPreferences 等。
- 避免在代码中硬编码密钥或敏感信息。
-
数据备份:
- 对敏感数据进行加密备份,避免备份数据泄露。
-
错误处理:
- 妥善处理加密操作中的异常,避免敏感信息泄露。