Flutter安全存储插件flutter_secure的使用

发布于 1周前 作者 bupafengyu 来自 Flutter

Flutter安全存储插件flutter_secure的使用

flutter_secure库简介

flutter_secure库是一个全面的Flutter包,为Flutter应用程序提供各种与安全相关的功能。它为开发者提供了增强Flutter应用安全性的工具,如检测root访问、实现SSL固定、安全键值存储、检测虚假位置、检测虚假设备和检测应用篡改。这些功能共同为更强大和安全的应用环境做出贡献,保护用户数据并确保应用执行的完整性。

drawing

安装

在你的pubspec.yaml文件中添加以下内容:

dependencies:
   flutter_secure: ^1.0.1

平台设置

Android 设置

  • 设置最低SDK版本: 在你的Android应用文件夹的build.gradle文件中将最低SDK版本设置为>=18:

    android {
      ..
      defaultConfig {
        ..
        minSdkVersion 18
      }
    }
    
  • 禁用自动备份: 我们需要禁用FlutterSecuredStorage的自动备份,因为恢复时会破坏安全存储。

    如果你希望完全禁用备份,在AndroidManifest.xml中添加以下内容:

    <application
      ...
      android:allowBackup="false"
      android:fullBackupContent="false">
    

    否则,你可以选择仅禁用安全存储的备份。在AndroidManifest.xml中添加以下内容:

    <application
      ...
      android:allowBackup="true"
      android:fullBackupContent="true"
      android:dataExtractionRules="@xml/data_extraction_rules">
    

    然后在res文件夹的xml文件夹中添加data_extraction_rules.xml文件,内容如下:

    <?xml version="1.0" encoding="utf-8"?>
    <data-extraction-rules>
      <cloud-backup>
        <include domain="sharedpref" path="."/>
        <exclude domain="sharedpref" path="FlutterSecureStorage"/>
      </cloud-backup>
    </data-extraction-rules>
    

iOS 设置

无需显式设置。

功能使用

Root检测

Root检测用于获取Android设备的root状态或iOS设备的越狱状态。要访问状态,可以参考以下代码片段:

void checkRooted() {
  FlutterSecure flutterSecure = FlutterSecure();
  bool rooted = await flutterSecure.isRooted;
  if (rooted) {
    // 设备已root或越狱
    // 实现适当的处理措施以应对已root的设备
  } else {
    // 设备未root或越狱
    // 继续正常的应用程序流程
  }
}

SSL固定

SSL固定用于将应用程序的网络请求固定到某个域。为此,受信任域的证书嵌入到应用程序中,并在每次从应用程序端向服务器发出请求时进行验证。

为了实现SSL固定,我们支持Flutter的两个流行网络库:http & Dio。

注意:使用的证书必须是PEM格式的字符串或文件。

SSL固定与Http

要使用SSL固定与Http,您可以使用我们的http客户端,提供受信任证书的列表作为字符串或文件。

// 使用字符串PEM证书
var client1 = SSLPinningHttpClient([pemCertificateString]);

// 使用文件PEM证书
var client2 = SSLPinningHttpClient.fromCertFiles([pemCertificateFile]);

// 使用client1或client2作为正常的http客户端来发起CRUD请求

当接收到的证书出现异常时,请求将不会被发出并且会抛出一个TlsException。确保将每个请求包裹在try-catch块中。

Http客户端使用示例:

try {
  var call = await client.get(Uri.parse('https://dreamorbit.com/'));
} on TlsException {
  // 接收的证书与受信任证书不同
}

SSL固定与Dio

要使用SSL固定与您的Dio客户端,您可以使用我们的Dio SSL固定拦截器,提供受信任证书的列表作为字符串或文件。

Dio dio1 = Dio()
  ..interceptors.add(SSLPinningInterceptor([pemCertificateString]));
Dio dio2 = Dio()
  ..interceptors.add(SSLPinningInterceptor.fromCertFiles([pemCertificateFile]));

// 使用dio1或dio2作为正常的http客户端来发起CRUD请求

当接收到的证书出现异常时,请求将不会被发出并且会抛出一个包含error属性为TlsExceptionDioException。确保将每个请求包裹在try-catch块中。

Dio拦截器使用示例:

try {
  var call = await dio.get('https://dreamorbit.com/');
} on DioException catch (e) {
  if (e.error is TlsException) {
    // 接收的证书与受信任证书不同
  } else {
    // 其他异常
  }
}

安全存储

安全存储使用平台的安全机制来存储键值对数据。您可以从插件的主要类访问安全存储实例:

var securedStorage = FlutterSecure().storage;

您可以在securedStorage上调用以下方法:

方法 目的
write 将特定keyvalue写入存储。此方法用于将数据安全地存储在存储中。
read 读取与特定key关联的值。返回存储的value或如果key不存在于存储中则返回null
readAll 检索存储中的所有键值对作为Map。此方法返回包含所有存储键值对的Map
delete 删除与特定key关联的值。此方法从存储中删除特定的键值对。
deleteAll 删除存储中的所有键值对。此方法清除整个存储,移除所有存储的数据。

虚假位置检测

此功能有助于检测设备是否具有伪造其位置的能力。这在设备提供的位置对于应用程序运行至关重要时很有帮助。

🚧 正在开发中

模拟器检测

此功能有助于检测托管应用程序的设备是真实设备还是模拟器。

🚧 正在开发中

篡改检测

此功能有助于确定应用程序是原始的还是被篡改的。这对于某些黑客重新编译应用程序混入自己的代码的情况非常有用。应用程序可以检测篡改并在应用程序启动时阻止应用程序流程。

🚧 正在开发中

许可证

BSD 3-Clause License
阅读LICENSE文件以获取详细信息。

变更日志

参阅Changelog以获取所有发布说明。

示例代码

以下是一个完整的示例demo,展示了如何使用flutter_secure插件检测设备是否已被root或越狱。

import 'package:flutter/material.dart';
import 'package:flutter_secure/flutter_secure.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  [@override](/user/override)
  void initState() {
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: Center(
          child: FutureBuilder<bool>(
            future: FlutterSecure().isRooted,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return Text('isRooted: ${snapshot.data}');
              } else if (snapshot.hasError) {
                return Text('Error: ${snapshot.error}');
              } else {
                return const Text('Loading...');
              }
            },
          ),
        ),
      ),
    );
  }
}

更多关于Flutter安全存储插件flutter_secure的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter安全存储插件flutter_secure的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter应用中使用flutter_secure_storage插件来实现安全存储的示例代码。这个插件允许你以安全的方式在设备上存储敏感信息,比如用户的认证令牌(tokens)、密码等。

首先,你需要在你的pubspec.yaml文件中添加flutter_secure_storage依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_secure_storage: ^5.0.2  # 请检查最新版本号

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter项目中,你可以按照以下步骤来使用这个插件:

  1. 导入插件

在你的Dart文件中(例如main.dart或者一个专门的服务文件中),导入flutter_secure_storage

import 'package:flutter_secure_storage/flutter_secure_storage.dart';
  1. 初始化存储

通常,你会在一个服务类中初始化并管理你的安全存储。这里是一个简单的例子:

class SecureStorageService {
  late FlutterSecureStorage storage;

  SecureStorageService() {
    storage = FlutterSecureStorage();
  }

  // 写数据到安全存储
  Future<void> writeData(String key, String value) async {
    await storage.write(key: key, value: value);
  }

  // 从安全存储读取数据
  Future<String?> readData(String key) async {
    return await storage.read(key: key);
  }

  // 删除安全存储中的数据
  Future<void> deleteData(String key) async {
    await storage.delete(key: key);
  }

  // 清除所有安全存储中的数据
  Future<void> clearAllData() async {
    await storage.deleteAll();
  }
}
  1. 使用服务

现在你可以在你的应用中使用这个服务来存储和读取敏感数据。例如,在一个登录成功后存储用户的认证令牌:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());

  // 示例:登录成功后存储令牌
  SecureStorageService secureStorageService = SecureStorageService();
  String userToken = "user-auth-token-12345";
  await secureStorageService.writeData("authToken", userToken);
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Secure Storage Demo'),
        ),
        body: Center(
          child: SecureStorageDemo(),
        ),
      ),
    );
  }
}

class SecureStorageDemo extends StatefulWidget {
  @override
  _SecureStorageDemoState createState() => _SecureStorageDemoState();
}

class _SecureStorageDemoState extends State<SecureStorageDemo> {
  late SecureStorageService secureStorageService;
  String? authToken;

  @override
  void initState() {
    super.initState();
    secureStorageService = SecureStorageService();

    // 示例:从安全存储中读取令牌
    secureStorageService.readData("authToken").then((value) {
      setState(() {
        authToken = value;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text("Auth Token: $authToken"),
        ElevatedButton(
          onPressed: () async {
            // 示例:删除令牌
            await secureStorageService.deleteData("authToken");
            setState(() {
              authToken = null;
            });
          },
          child: Text('Delete Auth Token'),
        ),
      ],
    );
  }
}

在这个例子中,我们创建了一个SecureStorageService类来管理安全存储的操作,包括写入、读取、删除和清除所有数据。在main函数中,我们演示了如何在登录成功后存储一个用户的认证令牌,然后在SecureStorageDemo组件中读取并显示这个令牌,并提供了一个按钮来删除这个令牌。

请注意,这只是一个基本的示例,实际应用中你可能需要添加更多的错误处理和安全性考虑。

回到顶部