基于最新版的flutter pointycastle: ^3.9.1的AES加密

基于最新版的flutter pointycastle: ^3.9.1的AES加密

自己添加pointycastle: ^3.9.1库

config.dart

dart 复制代码
import 'dart:convert';
import 'dart:typed_data';


class Config {
  static String password = '成都推理计算科技'; // 16字节(128位)的AES密钥
  static Uint8List iv = Uint8List.fromList([
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00
  ]); // 初始化向量(IV),对于AES/CBC/PKCS7Padding是必需的。自己按照ASCII表填点对自己有用的
  static int aesSize = 128;//可以填128,192,256
  static String aesSalt=latin1.decode([10, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);//salt可以用库里面的函数生成
}

aes_encrypt.dart

dart 复制代码
import 'dart:convert';
import 'dart:typed_data';

import 'package:pointycastle/pointycastle.dart';
import 'package:pointycastle/src/platform_check/platform_check.dart';
import 'config.dart';

class AesEncrypt {
  final iv = Config.iv;
  final password = Config.password;
  final aesSize = Config.aesSize;
  final aesSalt = Config.aesSalt;

  AesEncrypt();

  Uint8List aesCbcEncrypt(Uint8List key, Uint8List iv, Uint8List paddedPlaintext) {
    if (![128, 192, 256].contains(key.length * 8)) {
      throw ArgumentError.value(key, 'key', 'invalid key length for AES');
    }
    if (iv.length * 8 != 128) {
      throw ArgumentError.value(iv, 'iv', 'invalid IV length for AES');
    }
    if (paddedPlaintext.length * 8 % 128 != 0) {
      throw ArgumentError.value(paddedPlaintext, 'paddedPlaintext', 'invalid length for AES');
    }

    final cbc = BlockCipher('AES/CBC')..init(true, ParametersWithIV(KeyParameter(key), iv)); // true=encrypt

    final cipherText = Uint8List(paddedPlaintext.length); // allocate space

    var offset = 0;
    while (offset < paddedPlaintext.length) {
      offset += cbc.processBlock(paddedPlaintext, offset, cipherText, offset);
    }
    assert(offset == paddedPlaintext.length);

    return cipherText;
  }



  Uint8List aesCbcDecrypt(Uint8List key, Uint8List iv, Uint8List cipherText) {
    if (![128, 192, 256].contains(key.length * 8)) {
      throw ArgumentError.value(key, 'key', 'invalid key length for AES');
    }
    if (iv.length * 8 != 128) {
      throw ArgumentError.value(iv, 'iv', 'invalid IV length for AES');
    }
    if (cipherText.length * 8 % 128 != 0) {
      throw ArgumentError.value(cipherText, 'cipherText', 'invalid length for AES');
    }

    final cbc = BlockCipher('AES/CBC')..init(false, ParametersWithIV(KeyParameter(key), iv)); // false=decrypt

    final paddedPlainText = Uint8List(cipherText.length); // allocate space

    var offset = 0;
    while (offset < cipherText.length) {
      offset += cbc.processBlock(cipherText, offset, paddedPlainText, offset);
    }
    assert(offset == cipherText.length);

    return paddedPlainText;
  }


  String bin2hex(Uint8List bytes, {String? separator, int? wrap}) {
    var len = 0;
    final buf = StringBuffer();
    for (final b in bytes) {
      final s = b.toRadixString(16);
      if (buf.isNotEmpty && separator != null) {
        buf.write(separator);
        len += separator.length;
      }

      if (wrap != null && wrap < len + 2) {
        buf.write('\n');
        len = 0;
      }

      buf.write('${(s.length == 1) ? '0' : ''}$s');
      len += 2;
    }
    return buf.toString();
  }

  Uint8List hex2bin(String hexStr) {
    if (hexStr.length % 2 != 0) {
      throw const FormatException('not an even number of hexadecimal characters');
    }
    final result = Uint8List(hexStr.length ~/ 2);
    for (var i = 0; i < result.length; i++) {
      result[i] = int.parse(hexStr.substring(2 * i, 2 * (i + 1)), radix: 16);
    }
    return result;
  }

  Uint8List pad(Uint8List bytes, int blockSizeBytes) {
    final padLength = blockSizeBytes - (bytes.length % blockSizeBytes);

    final padded = Uint8List(bytes.length + padLength)..setAll(0, bytes);
    Padding('PKCS7').addPadding(padded, bytes.length);

    return padded;
  }



  Uint8List unpad(Uint8List padded) => padded.sublist(0, padded.length - Padding('PKCS7').padCount(padded));

  Uint8List passphraseToKey(String passPhrase, {String salt = '', int iterations = 30000, required int bitLength}) {
    if (![128, 192, 256].contains(bitLength)) {
      throw ArgumentError.value(bitLength, 'bitLength', 'invalid for AES');
    }
    final numBytes = bitLength ~/ 8;

    final kd = KeyDerivator('SHA-256/HMAC/PBKDF2')..init(Pbkdf2Parameters(utf8.encode(salt), iterations, numBytes));

    return kd.process(utf8.encode(passPhrase));
  }

  Uint8List? generateRandomBytes(int numBytes) {
    if (_secureRandom == null) {
      // First invocation: create _secureRandom and seed it
      _secureRandom = SecureRandom('Fortuna');
      _secureRandom!.seed(KeyParameter(Platform.instance.platformEntropySource().getBytes(32)));
    }

    // Use it to generate the random bytes

    final iv = _secureRandom!.nextBytes(numBytes);
    return iv;
  }

  SecureRandom? _secureRandom;

  Uint8List encrypt(String textToEncrypt) {
    final cipherText = aesCbcEncrypt(
        passphraseToKey(password, salt: aesSalt, bitLength: aesSize), iv, pad(utf8.encode(textToEncrypt), 16));
    return cipherText;
  }

  String decrypt(List<int> cipherListInt) {
    Uint8List cipherText = Uint8List.fromList(cipherListInt);
    final paddedDecryptedBytes =
        aesCbcDecrypt(passphraseToKey(password, salt: aesSalt, bitLength: aesSize), iv, cipherText);
    final decryptedBytes = unpad(paddedDecryptedBytes);
    final decryptedText = utf8.decode(decryptedBytes);
    return decryptedText;
  }
}
相关推荐
阿笑带你学前端2 小时前
Flutter本地通知系统:记账提醒的深度实现
前端·flutter
孤鸿玉20 小时前
Fluter InteractiveViewer 与ScrollView滑动冲突问题解决
flutter
叽哥1 天前
Flutter Riverpod上手指南
android·flutter·ios
BG2 天前
Flutter 简仿Excel表格组件介绍
flutter
zhangmeng2 天前
FlutterBoost在iOS26真机运行崩溃问题
flutter·app·swift
恋猫de小郭2 天前
对于普通程序员来说 AI 是什么?AI 究竟用的是什么?
前端·flutter·ai编程
卡尔特斯2 天前
Flutter A GlobalKey was used multipletimes inside one widget'schild list.The ...
flutter
w_y_fan2 天前
Flutter 滚动组件总结
前端·flutter
醉过才知酒浓2 天前
Flutter Getx 的页面传参
flutter
火柴就是我3 天前
flutter 之真手势冲突处理
android·flutter