基于最新版的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;
  }
}
相关推荐
2301_764441339 分钟前
使用python构建的应急物资代储博弈模型
开发语言·python·算法
丿BAIKAL巛11 分钟前
Java前后端传参与接收全解析
java·开发语言
code bean16 分钟前
【C++】Scoop 包管理器与 MinGW 工具链详解
开发语言·c++
yanghuashuiyue31 分钟前
Java过滤器-拦截器-AOP-Controller
java·开发语言
小冷coding35 分钟前
【Java】高并发架构设计:1000 QPS服务器配置与压测实战
java·服务器·开发语言
破刺不会编程1 小时前
socket编程TCP
linux·运维·服务器·开发语言·网络·网络协议·tcp/ip
北极糊的狐1 小时前
IDEA中安装 CamelCase 插件实现变量快速生成驼峰命名
开发语言·php
【蜡笔小新】1 小时前
《筑基篇》C语言基础2
c语言·开发语言
洛阳泰山2 小时前
Java实现周易六爻自动排盘:根据起卦的公历时间换算农和干支时间,推算日柱空亡(旬空)
java·开发语言·周易·六爻·算卦
奋斗的小鹰2 小时前
在已有Android工程中添加Flutter模块
android·flutter