实现思路
- 选择加密算法:可以选择AES(高级加密标准)等对称加密算法,它加解密速度快,适用于移动设备。
- 生成密钥:密钥需要安全存储,可使用Flutter的
flutter_secure_storage
插件存储在设备的安全区域。
- 加密存储:在将用户隐私信息存储到
SharedPreferences
之前,先使用选定的加密算法和密钥对信息进行加密。
- 解密读取:从
SharedPreferences
读取信息后,使用相同的密钥进行解密。
关键代码片段
- 引入依赖
dependencies:
shared_preferences: ^2.0.6
flutter_secure_storage: ^7.0.0
pointycastle: ^3.6.0
- 生成并存储密钥
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
final storage = FlutterSecureStorage();
Future<void> generateAndStoreKey() async {
// 生成随机密钥(这里简化示例,实际应更安全生成)
final key = 'yourRandomlyGeneratedKey1234567890';
await storage.write(key: 'encryptionKey', value: key);
}
- 加密数据
import 'package:pointycastle/export.dart';
import 'package:pointycastle/paddings/pkcs7.dart';
import 'package:pointycastle/modes/aes_gcm.dart';
Future<String> encryptData(String data) async {
final key = await storage.read(key: 'encryptionKey');
final keyBytes = key!.codeUnits;
final iv = Uint8List(12); // AES - GCM需要12字节IV
final plainText = data.codeUnits;
final blockCipher = AESGCMBlockCipher();
final gcmParameters = GCMParameters(iv, null, 128);
blockCipher.init(true, ParametersWithIV(KeyParameter(keyBytes), iv));
final padded = Pkcs7Padding().addPadding(plainText, blockCipher.blockSize);
final encrypted = blockCipher.process(padded);
return base64Encode(encrypted);
}
- 存储加密数据到SharedPreferences
import 'package:shared_preferences/shared_preferences.dart';
Future<void> saveEncryptedData(String encryptedData) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('encryptedLoginCredential', encryptedData);
}
- 解密数据
Future<String> decryptData(String encryptedData) async {
final key = await storage.read(key: 'encryptionKey');
final keyBytes = key!.codeUnits;
final encryptedBytes = base64Decode(encryptedData);
final iv = Uint8List(12);
final blockCipher = AESGCMBlockCipher();
final gcmParameters = GCMParameters(iv, null, 128);
blockCipher.init(false, ParametersWithIV(KeyParameter(keyBytes), iv));
final decrypted = blockCipher.process(encryptedBytes);
final unpadded = Pkcs7Padding().removePadding(decrypted, blockCipher.blockSize);
return String.fromCharCodes(unpadded);
}
- 读取并解密数据
Future<String?> readAndDecryptData() async {
final prefs = await SharedPreferences.getInstance();
final encryptedData = prefs.getString('encryptedLoginCredential');
if (encryptedData != null) {
return decryptData(encryptedData);
}
return null;
}