Flutter加密解密插件cryptography的使用

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

Flutter加密解密插件cryptography的使用

Overview

cryptography 是一个为Dart/Flutter开发者提供的流行密码学算法库。它由 gohilla.com 维护,采用Apache License 2.0许可证。

该包旨在:

  • 易于使用:API简单易懂且鼓励良好默认配置。
  • 多平台支持:易于在不同平台上定制实现。
  • 快速:尽可能利用平台API以提高性能。

如果你有反馈、问题或想要提交代码,请访问 Issue Tracker 或参与 Discussion

安装与配置

在你的 pubspec.yaml 文件中添加依赖项:

dependencies:
  cryptography: ^2.7.0
  cryptography_flutter: ^2.3.2 # 如果你使用Flutter的话可以加入此依赖

确保你已经安装了最新版本的Flutter SDK,并运行 flutter pub get 来获取所有依赖。

使用示例

数字签名(Ed25519)

以下是如何使用 Ed25519 进行数字签名和验证的完整示例:

import 'package:cryptography/cryptography.dart';

Future<void> main() async {
  // 待签名的消息
  final message = <int>[1, 2, 3];

  // 创建Ed25519算法实例并生成密钥对
  final algorithm = Ed25519();
  final keyPair = await algorithm.newKeyPair();

  // 签名消息
  final signature = await algorithm.sign(
    message,
    keyPair: keyPair,
  );
  print('Signature: ${signature.bytes}');
  print('Public key: ${signature.publicKey.bytes}');

  // 验证签名
  final isSignatureCorrect = await algorithm.verify(
    message,
    signature: signature,
  );
  print('Correct signature: $isSignatureCorrect');
}

密钥协商(X25519)

下面是一个使用 X25519 实现密钥协商的例子:

import 'package:cryptography/cryptography.dart';

Future<void> main() async {
  final algorithm = X25519();

  // Alice选择她的密钥对
  final aliceKeyPair = await algorithm.newKeyPair();

  // Alice知道Bob的公钥
  final bobKeyPair = await algorithm.newKeyPair();
  final bobPublicKey = await bobKeyPair.extractPublicKey();

  // Alice计算共享秘密
  final sharedSecret = await algorithm.sharedSecretKey(
    keyPair: aliceKeyPair,
    remotePublicKey: bobPublicKey,
  );
  final sharedSecretBytes = await sharedSecret.extractBytes();
  print('Shared secret: $sharedSecretBytes');
}

认证加密(AES-GCM)

这里展示了如何用 AES-GCM 对数据进行加密和解密:

import 'dart:convert';
import 'package:cryptography/cryptography.dart';

Future<void> main() async {
  // 选择加密算法
  final algorithm = AesGcm.with256bits();

  // 生成随机密钥
  final secretKey = await algorithm.newSecretKey();
  final secretKeyBytes = await secretKey.extractBytes();
  print('Secret key: ${secretKeyBytes}');

  // 加密
  final secretBox = await algorithm.encryptString(
    'Hello!',
    secretKey: secretKey,
  );
  print('Nonce: ${secretBox.nonce}');
  print('Ciphertext: ${secretBox.cipherText}');
  print('MAC: ${secretBox.mac}');
  
  // 将所有部分拼接起来以便传输
  final concatenatedBytes = secretBox.concatenation();
  print('All three parts concatenated: $concatenatedBytes');

  // 解密
  final clearText = await algorithm.decryptString(
    secretBox,
    secretKey: secretKey,
  );
  print('Cleartext: $clearText'); // Hello!
}

密码哈希(Argon2id)

最后是使用 Argon2id 进行密码哈希的例子:

import 'package:cryptography/cryptography.dart';

Future<void> main() async {
  final algorithm = Argon2id(
    memory: 10 * 1000, // 10 MB
    parallelism: 2, // 最多使用两个CPU核心
    iterations: 1, // 为了更高的安全性,通常应该增加memory参数而不是iterations
    hashLength: 32, // 返回哈希值的字节数
  );

  final secretKey = await algorithm.deriveKeyFromPassword(
    password: 'qwerty',
    nonce: [1, 2, 3],
  );
  final secretKeyBytes = await secretKey.extractBytes();

  print('Hash: ${secretKeyBytes}');
}

这些例子涵盖了从基本的加密解密到更复杂的密钥管理和密码保护等常见应用场景。希望这能帮助你在项目中更好地利用 cryptography 插件!如果有任何疑问或需要进一步的帮助,请随时查阅官方文档或向社区寻求支持。


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

1 回复

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


当然,以下是一个关于如何在Flutter应用中使用cryptography插件进行加密和解密的示例代码。cryptography插件允许你进行对称加密和非对称加密操作。在这个例子中,我们将展示如何使用AES进行对称加密和解密。

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

dependencies:
  flutter:
    sdk: flutter
  cryptography: ^2.0.0  # 请根据最新版本号进行调整

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

接下来,我们编写一个Flutter应用,展示如何使用AES进行加密和解密。

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

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

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

class CryptographyExample extends StatefulWidget {
  @override
  _CryptographyExampleState createState() => _CryptographyExampleState();
}

class _CryptographyExampleState extends State<CryptographyExample> {
  final _controller = TextEditingController();
  String _encryptedText = '';
  String _decryptedText = '';

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        TextField(
          controller: _controller,
          decoration: InputDecoration(labelText: 'Enter text to encrypt'),
          maxLines: 4,
        ),
        SizedBox(height: 16),
        ElevatedButton(
          onPressed: _encrypt,
          child: Text('Encrypt'),
        ),
        SizedBox(height: 16),
        Text('Encrypted Text: $_encryptedText'),
        SizedBox(height: 16),
        ElevatedButton(
          onPressed: _decrypt,
          child: Text('Decrypt'),
        ),
        SizedBox(height: 16),
        Text('Decrypted Text: $_decryptedText'),
      ],
    );
  }

  Future<void> _encrypt() async {
    final plainText = _controller.text;
    final key = Uint8List.fromList(List.generate(32, (index) => index % 256)); // 256-bit key
    final iv = Uint8List.fromList(List.generate(16, (index) => index % 256)); // 128-bit IV

    final aesGcm = AesGcm();
    final encrypted = await aesGcm.encrypt(
      plainText.codeUnits,
      secretKey: SecretKey.fromBytes(key),
      nonce: Nonce.fromBytes(iv),
    );

    setState(() {
      _encryptedText = base64Encode(encrypted.cipherText);
      _decryptedText = ''; // Clear decrypted text after encryption
    });
  }

  Future<void> _decrypt() async {
    final cipherTextBytes = base64Decode(_encryptedText);
    final key = Uint8List.fromList(List.generate(32, (index) => index % 256)); // Same key used for encryption
    final iv = Uint8List.fromList(List.generate(16, (index) => index % 256)); // Same IV used for encryption

    final aesGcm = AesGcm();
    final decrypted = await aesGcm.decrypt(
      GcmCipherText(cipherTextBytes, Uint8List.fromList([])), // Assuming no associated data
      secretKey: SecretKey.fromBytes(key),
      nonce: Nonce.fromBytes(iv),
    );

    setState(() {
      _decryptedText = String.fromCharCodes(decrypted.plainText);
    });
  }
}

代码说明:

  1. 依赖安装:在pubspec.yaml中添加cryptography依赖。
  2. UI布局:使用MaterialAppScaffold构建一个简单的UI,包含一个TextField用于输入文本,以及两个ElevatedButton用于触发加密和解密操作。
  3. 加密操作:在_encrypt方法中,使用AES-GCM算法对输入文本进行加密。生成一个256位的密钥和一个128位的IV(初始化向量),然后使用AesGcm类的encrypt方法进行加密。加密后的密文使用Base64编码以便于显示。
  4. 解密操作:在_decrypt方法中,将加密后的密文(Base64解码)使用相同的密钥和IV进行解密。解密后的明文显示在UI上。

请注意,在实际应用中,密钥和IV的管理应该更加安全,通常不应该硬编码在代码中。此外,对于生产环境,应使用安全的密钥管理服务和安全的随机数生成器。

回到顶部