Flutter加密解密插件rusty_chacha的使用

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

Flutter加密解密插件rusty_chacha的使用

Build Status Github Stars MIT License

Rusty ChaCha Banner

Rusty ChaCha 💃🦀

一个用于快速ChaCha20-Poly1305加密的Flutter库,利用了Rust的chacha20poly1305 crate的能力。

🚧 开发中:不推荐在生产环境中使用。 🚧


特性

  • 使用ChaCha20-Poly1305(认证)加密和解密数据
  • 支持附加认证数据(AAD)
  • 可选压缩功能,使用zstd算法

极速运行 🔥

由于Rust加密和解密,使用ChaCha20-Poly1305可以达到每秒500-1000 MB的速度。这比诸如cryptography_flutterpointycastle等包快多达50倍。


开始使用

在Flutter项目中,通过以下命令添加该库:

flutter pub add rusty_chacha

使用方法

import 'dart:typed_data';
import 'package:collection/collection.dart';
import 'package:rusty_chacha/rusty_chacha.dart';

void main() async {
  
  final data = Uint8List.fromList([1, 2, 3, 4, 5]);

  // 创建并使用一个随机密钥的ChaCha20Poly1305密码器:
  RustyChaCha20Poly1305 cipher = await RustyChaCha.create();
  Uint8List myEncryptedData = await cipher.encrypt(cleartext: data);
  Uint8List decrypted1 = await cipher.decrypt(ciphertext: myEncryptedData);

  assert(const ListEquality().equals(data, decrypted1));

  // 或者使用显式密钥:
  Uint8List key = await RustyChaCha20Poly1305.generateKey();
  cipher = await RustyChaCha.create(key: key);

  // 压缩示例:
  // 如果在加密时使用了压缩,则在解密时也必须设置!
  // 但是压缩级别并不重要。
  cipher = await RustyChaCha.create(
    key: key,
    compression: const Compression.zstd(compressionLevel: 3), // 中等压缩
  );
  Uint8List myCompressedAndEncryptedData = await cipher.encrypt(cleartext: data);
  Uint8List decrypted2 = await cipher.decrypt(ciphertext: myCompressedAndEncryptedData);

  assert(const ListEquality().equals(data, decrypted2));

  // AAD示例:
  cipher = await RustyChaCha.create();
  Uint8List additionalData = Uint8List.fromList([1, 2, 3]); // 某些额外的非机密数据
  Uint8List myEncryptedDataWithAad = await cipher.encrypt(
    cleartext: data,
    aad: additionalData, // 在加密时传递
  );
  Uint8List decrypted3 = await cipher.decrypt(
    ciphertext: myEncryptedDataWithAad,
    aad: additionalData, // 解密时传递(如果additionalData不同,则解密失败)
  );

  assert(const ListEquality().equals(data, decrypted3));

  // 创建并使用一个XChaCha20Poly1305,使用扩展的192位(24字节)随机数而不是96位(12字节):
  RustyXChaCha20Poly1305 cipherX = await RustyChaCha.createX();
  Uint8List myEncryptedData2 = await cipherX.encrypt(cleartext: data);
  Uint8List decrypted4 = await cipherX.decrypt(ciphertext: myEncryptedData2);

  assert(const ListEquality().equals(data, decrypted4));
}

当前支持的平台

  • iOS
  • MacOS
  • Windows
  • Linux

致谢

  • RustCrypto团队为创建了chacha20poly1305 crate
  • @fzyzcjy为提供了出色的flutter_rust_bridge
  • Mimir为提供了一个项目模板

完整示例代码

import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
import 'package:rusty_chacha/rusty_chacha.dart';

void _encrypt() async {
  final data = Uint8List.fromList([1, 2, 3, 4, 5]);
  print('data: $data');

  // 创建并使用一个随机密钥的ChaCha20Poly1305密码器:
  RustyChaCha20Poly1305 cipher = await RustyChaCha.create();

  Uint8List encrypted = await cipher.encrypt(cleartext: data);
  print('encrypted: $encrypted');

  Uint8List decrypted = await cipher.decrypt(ciphertext: encrypted);
  print('decrypted: $decrypted');

  assert(const ListEquality().equals(data, decrypted));
}

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Rusty ChaCha 💃🦀 demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Rusty ChaCha 💃🦀 demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      floatingActionButton: const FloatingActionButton(
        onPressed: _encrypt,
        tooltip: 'Encrypt',
        child: Icon(Icons.lock),
      ),
    );
  }
}

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

1 回复

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


当然,下面是一个关于如何在Flutter项目中使用rusty_chacha插件进行加密和解密的代码示例。rusty_chacha是一个基于Rust实现的Chacha20加密算法的Flutter插件。

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

dependencies:
  flutter:
    sdk: flutter
  rusty_chacha: ^最新版本号  # 请替换为实际的最新版本号

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

接下来,编写Flutter代码进行加密和解密操作。以下是一个完整的示例:

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

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String? encryptedText;
  String? decryptedText;
  String plainText = "Hello, Flutter and RustyChacha!";
  late Uint8List key;
  late Uint8List nonce;

  @override
  void initState() {
    super.initState();
    // 生成一个32字节的密钥(256位)和一个12字节的随机数(nonce)
    key = Uint8List.fromList(List.generate(32, (index) => index % 256));
    nonce = Uint8List.fromList(List.generate(12, (index) => index % 256));

    // 执行加密操作
    encryptText();
  }

  Future<void> encryptText() async {
    try {
      Uint8List encrypted = await RustyChacha.encrypt(plainText.codeUnits, key, nonce);
      setState(() {
        encryptedText = String.fromCharCodes(encrypted); // 这里仅用于显示,实际存储时应使用Base64或Hex编码
      });

      // 执行解密操作
      decryptText();
    } catch (e) {
      print("Encryption error: $e");
    }
  }

  Future<void> decryptText() async {
    try {
      if (encryptedText != null) {
        Uint8List encryptedBytes = Uint8List.fromList(encryptedText!.codeUnits);
        Uint8List decrypted = await RustyChacha.decrypt(encryptedBytes, key, nonce);
        setState(() {
          decryptedText = String.fromCharCodes(decrypted);
        });
      }
    } catch (e) {
      print("Decryption error: $e");
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('RustyChacha Encryption/Decryption Demo'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text('Plain Text: $plainText'),
              SizedBox(height: 16),
              if (encryptedText != null)
                Text('Encrypted Text: $encryptedText'),
              SizedBox(height: 16),
              if (decryptedText != null)
                Text('Decrypted Text: $decryptedText'),
            ],
          ),
        ),
      ),
    );
  }
}

注意事项:

  1. 密钥和随机数管理:在实际应用中,密钥和随机数应安全存储和管理。不要硬编码在代码中。
  2. 编码转换:由于加密后的数据是二进制数据,直接显示可能会有问题。通常使用Base64或Hex编码来转换二进制数据为字符串格式。
  3. 错误处理:在生产环境中,应添加更全面的错误处理逻辑。

编码转换示例(可选):

如果你希望将加密后的数据以Base64格式显示和存储,可以使用dart:convert库进行转换:

import 'dart:convert';

// 加密后转换为Base64
String encryptedBase64 = base64Encode(encrypted);
setState(() {
  encryptedText = encryptedBase64;
});

// 解密前从Base64转换回来
Uint8List encryptedBytes = base64Decode(encryptedBase64);

这样,你就可以在Flutter应用中安全地使用rusty_chacha插件进行加密和解密操作了。

回到顶部