Flutter如何实现AES GCM加密

在Flutter中如何正确实现AES GCM模式的加密和解密?我尝试使用pointycastle库,但不知道如何设置GCM所需的参数,比如IV和认证标签。能否提供一个完整的示例代码,包含密钥生成、加密和解密过程?特别需要注意哪些安全细节?

2 回复

Flutter中实现AES-GCM加密可以使用pointycastle库。以下是简单示例:

  1. 添加依赖:
dependencies:
  pointycastle: ^3.6.2
  1. 加密代码:
import 'package:pointycastle/export.dart';

Uint8List aesGcmEncrypt(
  Uint8List plaintext,
  Uint8List key,
  Uint8List nonce,
  Uint8List aad,
) {
  final cipher = GCMBlockCipher(AESEngine());
  final params = AEADParameters(
    KeyParameter(key),
    128,
    nonce,
    aad,
  );
  cipher.init(true, params);
  
  return cipher.process(plaintext);
}
  1. 解密代码:
Uint8List aesGcmDecrypt(
  Uint8List ciphertext,
  Uint8List key,
  Uint8List nonce,
  Uint8List aad,
) {
  final cipher = GCMBlockCipher(AESEngine());
  final params = AEADParameters(
    KeyParameter(key),
    128,
    nonce,
    aad,
  );
  cipher.init(false, params);
  
  return cipher.process(ciphertext);
}

注意:

  • nonce需要12字节
  • key需要16/24/32字节(对应AES-128/192/256)
  • 记得处理异常
  • 实际使用建议封装成类

更多关于Flutter如何实现AES GCM加密的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中实现AES GCM加密可以使用pointycastle包,以下是具体实现步骤:

1. 添加依赖

dependencies:
  pointycastle: ^3.6.2

2. 实现AES GCM加密解密类

import 'dart:convert';
import 'dart:typed_data';
import 'package:pointycastle/export.dart';

class AesGcmUtil {
  static const int keyLength = 32; // 256-bit key
  static const int ivLength = 12; // 96-bit IV for GCM
  static const int tagLength = 16; // 128-bit authentication tag

  // 加密方法
  static Map<String, Uint8List> encrypt(
      Uint8List plaintext, Uint8List key, Uint8List iv) {
    
    // 创建GCM块密码
    final cipher = GCMBlockCipher(AESEngine());
    
    // 创建参数:IV + 附加认证数据(可选)
    final params = AEADParameters(
      KeyParameter(key),
      tagLength * 8, // tag长度(比特)
      iv,
      Uint8List(0), // 附加数据,可为空
    );
    
    cipher.init(true, params); // true表示加密模式
    
    // 执行加密
    final ciphertext = cipher.process(plaintext);
    
    return {
      'ciphertext': ciphertext,
      'authTag': cipher.mac, // 获取认证标签
    };
  }

  // 解密方法
  static Uint8List decrypt(
      Uint8List ciphertext, Uint8List key, Uint8List iv, Uint8List authTag) {
    
    final cipher = GCMBlockCipher(AESEngine());
    
    final params = AEADParameters(
      KeyParameter(key),
      tagLength * 8,
      iv,
      Uint8List(0),
    );
    
    cipher.init(false, params); // false表示解密模式
    
    // 设置认证标签用于验证
    cipher.mac = authTag;
    
    // 执行解密
    return cipher.process(ciphertext);
  }

  // 生成随机IV
  static Uint8List generateIV() {
    final secureRandom = FortunaRandom();
    final seed = SecureRandom('SHA1/PRNG').nextBytes(32);
    secureRandom.seed(KeyParameter(seed));
    
    return secureRandom.nextBytes(ivLength);
  }
}

3. 使用示例

void main() {
  // 准备数据
  final plaintext = utf8.encode('Hello, AES-GCM!');
  final key = Uint8List.fromList(List.generate(32, (i) => i)); // 32字节密钥
  final iv = AesGcmUtil.generateIV(); // 生成随机IV

  // 加密
  final encrypted = AesGcmUtil.encrypt(
    Uint8List.fromList(plaintext),
    key,
    iv,
  );

  print('加密成功');
  print('IV: ${iv.sublist(0, 8)}...'); // 显示部分IV
  print('认证标签: ${encrypted['authTag']!.sublist(0, 8)}...');

  // 解密
  try {
    final decrypted = AesGcmUtil.decrypt(
      encrypted['ciphertext']!,
      key,
      iv,
      encrypted['authTag']!,
    );
    
    final decryptedText = utf8.decode(decrypted);
    print('解密结果: $decryptedText');
  } catch (e) {
    print('解密失败: $e'); // 认证失败会抛出异常
  }
}

关键要点

  1. 密钥长度: 支持128/192/256位,示例使用256位
  2. IV长度: GCM推荐使用12字节(96位)
  3. 认证标签: GCM提供完整性验证,解密失败会抛出异常
  4. 安全性: 每次加密应使用不同的IV

这种方法提供了强加密和完整性验证,适合需要高安全性的场景。

回到顶部