基于最新版的flutter pointycastle: ^3.9.1的AES加密 自己添加pointycastle: ^3.9.1库 config.dart aes_encrypt.dart
自己添加pointycastle: ^3.9.1库
config.dart
import 'dart:convert' ;
import 'dart:typed_data' ; class Config { static String password = '成都推理计算科技' ; static Uint8List iv = Uint8List . fromList ( [ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ] ) ; static int aesSize = 128 ; 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 ] ) ;
}
aes_encrypt.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) ) ; final cipherText = Uint8List ( paddedPlaintext. length) ; 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) ) ; final paddedPlainText = Uint8List ( cipherText. length) ; 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 ) { _secureRandom = SecureRandom ( 'Fortuna' ) ; _secureRandom! . seed ( KeyParameter ( Platform . instance. platformEntropySource ( ) . getBytes ( 32 ) ) ) ; } 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; }
}