Flutter流加密插件stream_cipher的使用

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

Flutter流加密插件stream_cipher的使用

安全文件

示例:

final secureFile = SecureFile(
   File('example'),
   encrypter: encrypter,
   decrypter: decrypter,
   useBase64: true,
   maxBlockSize: 4096,
 );

支持的功能:

  • Stream<Uint8List>读写
  • Uint8List读写
  • String读写

注意事项:

  • 加密/解密是在读取/写入时进行的,这意味着数据不会在读取或写入之前被加密或解密。
  • 解密器和加密器使用相同的方法。注意:对于内部加密器(如AES、RSA、Gzip、NoEncryption),有断言检查。如果你扩展了De/Encrypter类,你需要在你的应用中测试它。在某些情况下,这可能看起来没问题,但在实际操作中,在读取文件内容时可能会导致错误甚至数据损坏。
  • 这个类不扩展File类。
  • write方法支持追加到文件。在这种情况下,你需要通过构造函数传递一个EncryptStreamMeta对象,并使用相同的值设置SeparatorEnding,例如EncryptStreamMeta.sameSeparatorAsEnding('....... separator .......')
  • 由于一些算法在加密和解密过程中的高负载,这个类不支持同步读写。
  • 类中的方法不在隔离中运行,因此可能会导致性能问题。

DioHttpAdapter

示例:

/// 创建CipherDioHttpAdapter实例
final dioClient = CipherDioHttpAdapter(
     decrypter: decrypter,
     encrypter: encrypter,
   );
/// 使用CipherDioHttpAdapter创建Dio实例
final dio = Dio()..httpClientAdapter = dioClient;

注意事项:

  • 在此方法中,仅请求的主体部分被加密。
  • 在此方法中,仅响应的主体部分被解密。
  • 请求头未加密。要修改请求头,你可以扩展其中一个IByteDataEncrypter并重写alterHeader方法以实现这一点。

示例解密器/加密器

示例:

final encrypter = AESByteDataEncrypter.randomSecureKey();
final decrypter = AESByteDataDecrypter(
  key: encrypter.key,
  iv: encrypter.iv,
);

完整示例Demo

import 'dart:io';

import 'package:dio/dio.dart';
import 'package:logger/logger.dart';
import 'package:stream_cipher/src/io_utils/client_adapters/dio_client_adapter.dart';
import 'package:stream_cipher/src/io_utils/file/secure_file.dart';
import 'package:stream_cipher/stream_cipher.dart';

import 'sample_dart_backend.dart';

const kServerPort = 40881;
const kMessage =
    '''{"note":"ممد اینجاس","extras":"Enim aliquip adipisicing cillum. Enim laborum sint ad duis consequat sunt ad tempor laborum voluptate ea enim reprehenderit consequat eiusmod. Eu sit culpa ipsum irure occaecat tempor do. Culpa aute do ipsum elit esse est consequat in aliqua ea consequat ut excepteur in. Ex nulla exercitation labore cupidatat Lorem exercitation pariatur dolore dolor.Sit est irure cillum esse est pariatur dolor quis exercitation ullamco ea. Est labore officia incididunt ipsum sunt ullamco ea cillum ad exercitation occaecat sit adipisicing. Et exercitation veniam magna cupidatat quis culpa ut tempor. Ea sint ullamco consectetur do laboris pariatur cupidatat anim cillum ipsum aliqua consequat velit nostrud. Irure aliquip adipisicing culpa dolore. Cupidatat aliqua voluptate aliqua exercitation sit commodo esse in id duis cupidatat veniam laboris occaecat incididunt. Anim officia ullamco cupidatat elit consectetur dolor adipisicing dolore duis consequat in sint qui.Enim aliquip adipisicing cillum. Enim laborum sint ad duis consequat sunt ad tempor laborum voluptate ea enim reprehenderit consequat eiusmod. Eu sit culpa ipsum irure occaecat tempor do. Culpa aute do ipsum elit esse est consequat in aliqua ea consequat ut excepteur in. Ex nulla exercitation labore cupidatat Lorem exercitation pariatur dolore dolor.Sit est irure cillum esse est pariatur dolor quis exercitation ullamco ea. Est labore officia incididunt ipsum sunt ullamco ea cillum ad exercitation occaecat sit adipisicing. Et exercitation veniam magna cupidatat quis culpa ut tempor. Ea sint ullamco consectetur do laboris pariatur cupidatat anim cillum ipsum aliqua consequat velit nostrud. Irure aliquip adipisicing culpa dolore. Cupidatat aliqua voluptate aliqua exercitation sit commodo esse in id duis cupidatat veniam laboris occaecat incididunt. Anim officia ullamco cupidatat elit consectetur dolor adipisicing dolore duis consequat in sint qui.Enim aliquip adipisicing cillum. Enim laborum sint ad duis consequat sunt ad tempor laborum voluptate ea enim reprehenderit consequat eiusmod. Eu sit culpa ipsum irure occaecat tempor do. Culpa aute do ipsum elit esse est consequat in aliqua ea consequat ut excepteur in. Ex nulla exercitation labore cupidatat Lorem exercitation pariatur dolore dolor.Sit est irure cillum esse est pariatur dolor quis exercitation ullamco ea. Est labore officia incididunt ipsum sunt ullamco ea cillum ad exercitation occaecat sit adipisicing. Et exercitation veniam magna cupidatat quis culpa ut tempor. Ea sint ullamco consectetur do laboris pariatur cupidatat anim cillum ipsum aliqua consequat velit nostrud. Irure aliquip adipisicing culpa dolore. Cupidatat aliqua voluptate aliqua exercitation sit commodo esse in id duis cupidatat veniam laboris occaecat incididunt. Anim officia ullamco cupidatat elit consectetur dolor adipisicing dolore duis consequat in sint qui.Enim aliquip adipisicing cillum. Enim laborum sint ad duis consequat sunt ad tempor laborum voluptate ea enim reprehenderit consequat eiusmod. Eu sit culpa ipsum irure occaecat tempor do. Culpa aute do ipsum elit esse est consequat in aliqua ea consequat ut excepteur in. Ex nulla exercitation labore cupidatat Lorem exercitation pariatur dolore dolor.Sit est irure cillum esse est pariatur dolor quis exercitation ullamco ea. Est labore officia incididunt ipsum sunt ullamco ea cillum ad exercitation occaecat sit adipisicing. Et exercitation veniam magna cupidatat quis culpa ut tempor. Ea sint ullamco consectetur do laboris pariatur cupidatat anim cillum ipsum aliqua consequat velit nostrud. Irure aliquip adipisicing culpa dolore. Cupidatat aliqua voluptate aliqua exercitation sit commodo esse in id duis cupidatat veniam laboris occaecat incididunt. Anim officia ullamco cupidatat elit consectetur dolor adipisicing dolore duis consequat in sint qui.Enim aliquip adipisicing cillum. Enim laborum sint ad duis consequat sunt ad tempor laborum voluptate ea enim reprehenderit consequat eiusmod. Eu sit culpa ipsum irure occaecat tempor do. Culpa aute do ipsum elit esse est consequat in aliqua ea consequat ut excepteur in. Ex nulla exercitation labore cupidatat Lorem exercitation pariatur dolore dolor.Sit est irure cillum esse est pariatur dolor quis exercitation ullamco ea. Est labore officia incididunt ipsum sunt ullamco ea cillum ad exercitation occaecat sit adipisicing. Et exercitation veniam magna cupidatat quis culpa ut tempor. Ea sint ullamco consectetur do laboris pariatur cupidatat anim cillum ipsum aliqua consequat velit nostrud. Irure aliquip adipisicing culpa dolore. Cupidatat aliqua voluptate aliqua exercitation sit commodo esse in id duis cupidatat veniam laboris occaecat incididunt. Anim officia ullamco cupidatat elit consectetur dolor adipisicing dolore duis consequat in sint qui.Enim aliquip adipisicing cillum. Enim laborum sint ad duis consequat sunt ad tempor laborum voluptate ea enim reprehenderit consequat eiusmod. Eu sit culpa ipsum irure occaecat tempor do. Culpa aute do ipsum elit esse est consequat in aliqua ea consequat ut excepteur in. Ex nulla exercitation labore cupidatat Lorem exercitation pariatur dolore dolor.Sit est irure cillum esse est pariatur dolor quis exercitation ullamco ea. Est labore officia incididunt ipsum sunt ullamco ea cillum ad exercitation occaecat sit adipisicing. Et exercitation veniam magna cupidatat quis culpa ut tempor. Ea sint ullamco consectetur do laboris pariatur cupidatat anim cillum ipsum aliqua consequat velit nostrud. Irure aliquip adipisicing culpa dolore. Cupidatat aliqua voluptate aliqua exercitation sit commodo esse in id duis cupidatat veniam laboris occaecat incididunt. Anim officia ullamco cupidatat elit consectetur dolor adipisicing dolore duis consequat in sint qui.Enim aliquip adipisicing cillum. Enim laborum sint ad duis consequat sunt ad tempor laborum voluptate ea enim reprehenderit consequat eiusmod. Eu sit culpa ipsum irure occaecat tempor do. Culpa aute do ipsum elit esse est consequat in aliqua ea consequat ut excepteur in. Ex nulla exercitation labore cupidatat Lorem exercitation pariatur dolore dolor.Sit est irure cillum esse est pariatur dolor quis exercitation ullamco ea. Est labore officia incididunt ipsum sunt ullamco ea cillum ad exercitation occaecat sit adipisicing. Et exercitation veniam magna cupidatat quis culpa ut tempor. Ea sint ullamco consectetur do laboris pariatur cupidatat anim cillum ipsum aliqua consequat velit nostrud. Irure aliquip adipisicing culpa dolore. Cupidatat aliqua voluptate aliqua exercitation sit commodo esse in id duis cupidatat veniam laboris occaecat incididunt. Anim officia ullamco cupidatat elit consectetur dolor adipisicing dolore duis consequat in sint qui."}''';
// const kRawEchoApiUrl = 'http://0.0.0.0:3000/example/echo_server.php';
const kDecodedEchoAPIUrl = 'http://127.0.0.1:$kServerPort/decoded_echo';
const kRawEchoApiUrl = 'http://127.0.0.1:$kServerPort/raw_echo';
const kMiddleEchoApiUrl = 'http://127.0.0.1:$kServerPort/middle_cipher';
const kMaxPartSize = 600;
final logger = Logger();
Future<void> main() async {
  final server = await dartBackEnd();
  await rrrr();
  await errr();
  await erdr();
  await erdr2();
  await erdr3();
  await ioWriteAndRead();
  server.close(force: true);
}

final testFile = File('test.test');
const streamMeta = EncryptStreamMeta(
  ending: '#ENDING#',
  separator: '#=#',
);
Future<void> ioWriteAndRead() async {
  final encrypter = AESByteDataEncrypter.empty();
  final decrypter = AESByteDataDecrypter(key: encrypter.key, iv: encrypter.iv);
  const testData =
      '''Elit mollit Lorem et cillum voluptate id aliqua. Ipsum velit mollit duis cupidatat exercitation aliqua excepteur eu anim excepteur ad. Sint dolor eiusmod aliquip proident elit. Qui cupidatat veniam minim do cillum enim aute veniam sit duis. Voluptate quis consectetur duis reprehenderit. Excepteur sunt occaecat in labore ea consequat dolor culpa ex aliquip aute consequat.
Culpa do labore id. Ex ea sunt veniam. Occaecat Lorem occaecat culpa laboris fugiat dolore sit labore. Enim excepteur sit amet do laboris mollit esse nulla do occaecat pariatur id. Ut sit sit sit velit tempor dolore adipisicing pariatur aliquip aute cillum ipsum.''';
  final secureFile = SecureFile(
    testFile,
    encrypter: encrypter,
    decrypter: decrypter,
    // streamMeta: streamMeta,
    useBase64: false,
    maxBlockSize: kMaxPartSize,
  );
  await secureFile.writeString(
    testData,
  );
  final readData = await secureFile.readString();

  logger.i(
    'read value: $readData',
    null,
    StackTrace.fromString('DartExample'),
  );
}

Future<void> rrrr() async {
  final encrypter = NoEncryptionByteDataEncrypter();
  final decrypter = NoEncryptionByteDataDecrypter();
  final dioClient = CipherDioHttpAdapter(
    decrypter: decrypter,
    encrypter: encrypter,
    maximumPartSize: kMaxPartSize,
  );

  final dio = Dio()..httpClientAdapter = dioClient;
  await dio
      .post(
    kRawEchoApiUrl,
    data: kMessage,
  )
      .then((response) {
    logger.i(
      'Raw echo request -> Raw response: ${response.data}',
      null,
      StackTrace.fromString('DartExample'),
    );
  });
}

Future<void> errr() async {
  final encrypter = AESByteDataEncrypter.empty();
  final decrypter = NoEncryptionByteDataDecrypter();
  final dioClient = CipherDioHttpAdapter(
    decrypter: decrypter,
    encrypter: encrypter,
    maximumPartSize: kMaxPartSize,
  );

  final dio = Dio()..httpClientAdapter = dioClient;
  await dio
      .post(
    kRawEchoApiUrl,
    data: kMessage,
  )
      .then((response) {
    logger.i(
      'Encrypted echo request -> raw response: ${response.data}',
      null,
      StackTrace.fromString('DartExample'),
    );
  });
}

Future<void> erdr() async {
  final encrypter = AESByteDataEncrypter.randomSecureKey();
  final decrypter = AESByteDataDecrypter(key: encrypter.key, iv: encrypter.iv);
  final dioClient = CipherDioHttpAdapter(
    decrypter: decrypter,
    encrypter: encrypter,
    maximumPartSize: kMaxPartSize,
  );
  final dio = Dio()..httpClientAdapter = dioClient;

  await dio
      .post(
    kRawEchoApiUrl,
    data: kMessage,
  )
      .then((response) {
    logger.i(
      'Encrypted echo request -> decrypted response: ${response.data}',
      null,
      StackTrace.fromString('DartExample'),
    );
  });
}

Future<void> erdr2() async {
  final encrypter = AESByteDataEncrypter.empty();
  final decrypter = NoEncryptionByteDataDecrypter();
  final dioClient = CipherDioHttpAdapter(
    decrypter: decrypter,
    encrypter: encrypter,
    maximumPartSize: kMaxPartSize,
  );

  final dio = Dio()..httpClientAdapter = dioClient;

  final response = await dio.post(
    kDecodedEchoAPIUrl,
    data: kMessage,
  );
  logger.i(
    'Encrypted request -> decrypted in backend: ${response.data}',
    null,
    StackTrace.fromString('DartExample'),
  );
}

Future<void> erdr3() async {
  final encrypter = AESByteDataEncrypter.empty();
  final decrypter = NoEncryptionByteDataDecrypter();
  final dioClient = CipherDioHttpAdapter(
    decrypter: decrypter,
    encrypter: encrypter,
    maximumPartSize: kMaxPartSize,
  );

  final dio = Dio()..httpClientAdapter = dioClient;

  final response = await dio.post(
    kMiddleEchoApiUrl,
    data: kMessage,
  );
  logger.i(
    'Encrypted request -> decrypted in backend (MiddleWare): ${response.data}',
    null,
    StackTrace.fromString('DartExample'),
  );
}

更多关于Flutter流加密插件stream_cipher的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter流加密插件stream_cipher的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用stream_cipher插件进行流加密的示例代码。stream_cipher插件通常用于对数据进行对称加密和解密,这里我们假设你使用的是AES算法。

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

dependencies:
  flutter:
    sdk: flutter
  pointycastle: ^3.0.1  # stream_cipher 依赖于 pointycastle
  stream_cipher: ^0.2.0  # 请根据最新版本号进行调整

然后,运行flutter pub get来获取依赖。

接下来,我们编写一个示例代码来演示如何使用stream_cipher进行AES加密和解密。

import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:pointycastle/export.dart';
import 'package:stream_cipher/stream_cipher.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Stream Cipher Example'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Center(
            child: StreamCipherExample(),
          ),
        ),
      ),
    );
  }
}

class StreamCipherExample extends StatefulWidget {
  @override
  _StreamCipherExampleState createState() => _StreamCipherExampleState();
}

class _StreamCipherExampleState extends State<StreamCipherExample> {
  String? encryptedText;
  String? decryptedText;

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

  Future<void> _performEncryptionAndDecryption() async {
    String plainText = "Hello, Flutter!";
    Uint8List key = Uint8List.fromList(List.generate(32, (index) => index % 256)); // 256-bit key
    Uint8List iv = Uint8List.fromList(List.generate(16, (index) => index % 256)); // Initialization Vector (IV)

    // Create AES-CTR stream cipher
    final KeyParameter keyParam = KeyParameter(key);
    final ParametersWithIV<KeyParameter> params = ParametersWithIV<KeyParameter>(keyParam, iv);
    final Salsa20Cipher salsa20 = Salsa20Cipher();
    final StreamCipher streamCipher = StreamCipher('AES/CTR')
      ..init(true, params);

    // Convert plain text to Uint8List
    Uint8List plainTextBytes = Uint8List.fromList(plainText.codeUnits);

    // Encrypt
    Uint8List encryptedBytes = Uint8List(plainTextBytes.length);
    for (int i = 0; i < plainTextBytes.length; i++) {
      encryptedBytes[i] = plainTextBytes[i] ^ streamCipher.processByte(0);
    }

    // Convert encrypted bytes back to a string (for display purposes, not secure)
    String encryptedString = base64Encode(encryptedBytes);
    setState(() {
      encryptedText = encryptedString;
    });

    // Decrypt (reset stream cipher for decryption, though for CTR mode it's not strictly necessary)
    streamCipher.init(false, params);
    Uint8List decryptedBytes = Uint8List(plainTextBytes.length);
    for (int i = 0; i < plainTextBytes.length; i++) {
      decryptedBytes[i] = encryptedBytes[i] ^ streamCipher.processByte(0);
    }

    // Convert decrypted bytes back to a string
    String decryptedString = String.fromCharCodes(decryptedBytes);
    setState(() {
      decryptedText = decryptedString;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('Plain Text: Hello, Flutter!'),
        SizedBox(height: 16),
        Text('Encrypted Text: $encryptedText'),
        SizedBox(height: 16),
        Text('Decrypted Text: $decryptedText'),
      ],
    );
  }
}

注意

  1. 在实际应用中,密钥(key)和初始化向量(IV)应该安全地生成和存储。
  2. 上面的代码仅用于演示目的,并不是生产级别的安全代码。在生产环境中,请确保你遵循最佳安全实践。
  3. stream_cipher插件依赖于pointycastle库,因此你需要在代码中导入pointycastle
  4. 对于AES加密,我们使用了CTR模式(AES/CTR),它允许我们进行流加密。

运行这个Flutter应用,你会看到原始文本被加密,然后又被解密回原始文本。

回到顶部