MST

星途 面试题库

面试题:Flutter中如何使用SharedPreferences确保数据存储的基本安全性

在Flutter开发中,常使用SharedPreferences进行简单数据存储。请描述如何对存储在SharedPreferences中的用户隐私信息(如登录凭证)进行基本的安全处理,以防止信息轻易泄露,比如采取加密等措施,简要说明实现思路及关键代码片段。
26.0万 热度难度
前端开发Flutter

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 选择加密算法:可以选择AES(高级加密标准)等对称加密算法,它加解密速度快,适用于移动设备。
  2. 生成密钥:密钥需要安全存储,可使用Flutter的flutter_secure_storage插件存储在设备的安全区域。
  3. 加密存储:在将用户隐私信息存储到SharedPreferences之前,先使用选定的加密算法和密钥对信息进行加密。
  4. 解密读取:从SharedPreferences读取信息后,使用相同的密钥进行解密。

关键代码片段

  1. 引入依赖
dependencies:
  shared_preferences: ^2.0.6
  flutter_secure_storage: ^7.0.0
  pointycastle: ^3.6.0
  1. 生成并存储密钥
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);
}
  1. 加密数据
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);
}
  1. 存储加密数据到SharedPreferences
import 'package:shared_preferences/shared_preferences.dart';

Future<void> saveEncryptedData(String encryptedData) async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.setString('encryptedLoginCredential', encryptedData);
}
  1. 解密数据
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);
}
  1. 读取并解密数据
Future<String?> readAndDecryptData() async {
  final prefs = await SharedPreferences.getInstance();
  final encryptedData = prefs.getString('encryptedLoginCredential');
  if (encryptedData != null) {
    return decryptData(encryptedData);
  }
  return null;
}