Flutter安全增强插件flutter_security的使用

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

Flutter安全增强插件flutter_security的使用

flutter_security 是一个旨在处理移动应用安全问题的 Flutter 包。

hasBundleBeenCompromised

此功能仅在 iOS 上可用。

主要概念是检查 Frameworks(位于主 bundle 根目录)文件夹内文件的 MD5 值与预编译的 JSON 文件进行对比。

该 JSON 文件是通过以下脚本生成的: 此脚本。 建议使用 AES CBC 模式加密保护 JSON 文件。

工作流程

这是我的操作步骤:

  1. 构建应用以获取所需的所有文件。
  2. 将上述脚本复制到刚刚构建的 .app 文件中。这样可以生成包含相对路径的文件。
  3. 使用所有必需的参数运行脚本(例如 ./msh-darwin-amd64 generate-map --files Frameworks --key some_random_key_phrase)。
  4. 检查 .app 中是否生成了 encrypted.json
  5. 如需使用该包,可按以下方式使用(例如):
final result = await FlutterSecurity.hasBundleBeenCompromised(
  iosSecurityOptions: IosSecurityOptions(
      bundleId: 'com.example.flutterSecurityExample',
      jsonFileName: 'encrypted.json',
      cryptographicKey: 'k4rAN45oL8LxH21wX2nRTDB5o1uYnnrB'),
);

然后你可以根据需要使用 result(例如,在攻击正在进行时使应用崩溃)。

amITampered

此功能结合了 IOSSecuritySuite 和一些 StackOverflow 的有用文章(这些文章的链接已丢失)用于 Android 实现。

反篡改功能检查应用程序使用的签名与你发送的作为真相来源的签名之间的匹配情况。

Android

要在 Android 上检查反篡改,你需要提供应用密钥库的 SHA-1 值。如果你处于调试模式且尚未创建密钥库,则会为你的应用分配一个 SHA。请检查你的应用级 build.gradle

iOS

要在 iOS 上检查反篡改,需要做更多的工作。如这里所述,你需要提供 bundleIdmobile.provision 文件(包含在构建的 .ipa 文件中)的哈希值:

  1. 解压 .ipa 文件。
  2. 进入 payload 文件夹,右键点击应用并选择“显示包内容”。
  3. 你应该看到名为 “test” 的 Unix 可执行文件(在这个例子中是 “test”)。

打开终端并执行以下步骤:

  1. otool -l /path/to/unix/executable
  2. 查找 segname __TEXT 中的 offsetsize 值。
  3. 将这两个值保存下来。
  4. 运行 dd if=test.ipa ibs=1 skip=<offset> count=<size> | shasum -a 256
  5. 保存 SHA256 并在代码中使用它。

示例代码

以下是使用 flutter_security 的完整示例代码:

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_security/flutter_security.dart';
import 'package:flutter_security/helpers/platform_options.dart';
import 'package:flutter_security/helpers/response_codes.dart';

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

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String? _amItamperedResponse = 'Let me check';

  [@override](/user/override)
  void initState() {
    super.initState();
    initPlatformState();
  }

  Future<void> initPlatformState() async {
    ResponseSecurityCodes amItampered;
    amItampered = await FlutterSecurity.amITampered(
      iosSecurityOptions: IosSecurityOptions(
          bundleId: 'com.example.flutterSecurityExample',
          mobileProvision: 'some_hash_values'),
      androidSecurityOptions: AndroidSecurityOptions(sha1: 'some_sha1_values'),
    );

    if (!mounted) return;

    await Future.delayed(Duration(seconds: 1));
    setState(() {
      switch (amItampered) {
        case ResponseSecurityCodes.tampered:
          _amItamperedResponse = 'YES!!!';
          break;
        case ResponseSecurityCodes.notTampered:
          _amItamperedResponse = 'No.';
          break;
        case ResponseSecurityCodes.genericError:
          _amItamperedResponse = 'Unable to check, something goes wrong';
          break;
        case ResponseSecurityCodes.missingParametersError:
          _amItamperedResponse = 'Missing parameters';
          break;
        case ResponseSecurityCodes.unavailable:
          _amItamperedResponse = 'Unavailable';
          break;
      }
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('插件示例应用'),
        ),
        body: Center(
          child: Column(
            children: [
              Text('我是被篡改了吗?\n$_amItamperedResponse\n'),
              ElevatedButton(
                onPressed: () async {
                  final time = DateTime.now();
                  final result = await FlutterSecurity.hasBundleBeenCompromised(
                    iosSecurityOptions: IosSecurityOptions(
                        bundleId: 'com.example.flutterSecurityExample',
                        jsonFileName: 'encrypted.json',
                        cryptographicKey: 'k4rAN45oL8LxH21wX2nRTDB5o1uYnnrB'),
                  );
                  print(
                      '总捆绑检查完成时间:${DateTime.now().difference(time).inMilliseconds}ms');
                  print(result);
                },
                child: Text('检查'),
              ),
              SizedBox(
                height: 50,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

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

1 回复

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


当然,下面是一个关于如何使用Flutter安全增强插件flutter_security的示例代码。这个插件可以帮助开发者增强Flutter应用的安全性,例如防止截图、检测root/jailbreak设备等。

首先,确保你已经在pubspec.yaml文件中添加了flutter_security依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_security: ^x.y.z  # 请替换为最新版本号

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

接下来,在你的Flutter应用中,你可以按照以下方式使用flutter_security插件:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  bool _isRooted = false;
  bool _isScreenshotProtected = false;

  @override
  void initState() {
    super.initState();
    initSecurityChecks();
  }

  Future<void> initSecurityChecks() async {
    // 检查设备是否root或jailbreak
    try {
      bool isRooted = await FlutterSecurity.checkDeviceRooted();
      setState(() {
        _isRooted = isRooted;
      });
    } catch (e) {
      print("Error checking device root status: $e");
    }

    // 启用截图保护
    try {
      bool isScreenshotProtected = await FlutterSecurity.preventScreenCapture(true);
      setState(() {
        _isScreenshotProtected = isScreenshotProtected;
      });
    } catch (e) {
      print("Error enabling screenshot protection: $e");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Security Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text(
              'Device Rooted: $_isRooted',
              style: TextStyle(fontSize: 18),
            ),
            SizedBox(height: 16),
            Text(
              'Screenshot Protection Enabled: $_isScreenshotProtected',
              style: TextStyle(fontSize: 18),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们做了以下几件事:

  1. 检查设备是否Root或Jailbreak:使用FlutterSecurity.checkDeviceRooted()方法来检查设备是否已被root或jailbreak。结果会显示在UI上。

  2. 启用截图保护:使用FlutterSecurity.preventScreenCapture(true)方法来启用截图保护。如果启用成功,结果也会显示在UI上。

请注意,flutter_security插件的功能可能因平台(iOS/Android)而异,某些功能可能只在特定平台上可用。因此,在实际开发中,请务必查阅插件的官方文档以了解详细的平台支持和功能说明。

此外,安全性是一个复杂的领域,单一插件可能无法覆盖所有安全需求。因此,建议结合其他安全措施(如代码混淆、HTTPS通信等)来增强应用的整体安全性。

回到顶部