Dart:使用 PointyCastle 插件在 AES 中加密和解密

问题描述 投票:0回答:2

我正在尝试使用下面将向您展示的插件来执行加密和解密。

解密对我来说非常有效,因为我使用了后端的 AES 密码,并且它完美地转换了它。

问题如下: 当你加密时,得到结果并想在 dart 中解密,它没有给出预期的结果。

我猜IV和SALT我做错了,我希望得到一些建议或帮助,谢谢。

pub.dev 中的 PointyCastle

crypto.dart

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

class Crypto {
  static const String password = "password_here";
  static const String algorithm = "AES";
  static FortunaRandom? _secureRandom;

  /// [decrypt] Method
  /// Requires one parameter: ```cipherText```
  static String decrypt( String cipherText ) {
    CBCBlockCipher cipher = CBCBlockCipher(BlockCipher( algorithm ));
    
    Uint8List ciphertextlist = base64.decode(cipherText);
    Uint8List salt = generateRandomBytes(32);
    Uint8List key = _generateKey(password, salt);
    Uint8List iv = generateRandomBytes(128 ~/ 8);
    Uint8List encrypted = ciphertextlist.sublist(20 + 16);

    ParametersWithIV<KeyParameter> params = ParametersWithIV<KeyParameter>(KeyParameter(key), iv);
    PaddedBlockCipherParameters<ParametersWithIV<KeyParameter>, KeyParameter> paddingParams = PaddedBlockCipherParameters<ParametersWithIV<KeyParameter>, KeyParameter>(params, null);
    PaddedBlockCipherImpl paddingCipher = PaddedBlockCipherImpl(PKCS7Padding(), cipher);
    paddingCipher.init(false, paddingParams);
    var val = paddingCipher.process(encrypted);
    String decrypted = String.fromCharCodes(val);
    return decrypted;
  }

  /// [encrypt] Method
  /// Requieres one parameter: ```plainText```
  static String encrypt( String plainText ) {
    final CBCBlockCipher cbcCipher = CBCBlockCipher(BlockCipher( algorithm ));
    List<int> data = utf8.encode( plainText );
    Uint8List iv = generateRandomBytes(128 ~/ 8);
    Uint8List salt = generateRandomBytes(32);
    Uint8List key = _generateKey(password, Uint8List.fromList(salt));
    final ParametersWithIV<KeyParameter> ivParams = ParametersWithIV<KeyParameter>(KeyParameter(key), iv);
    final PaddedBlockCipherParameters<ParametersWithIV<KeyParameter>, KeyParameter> paddingParams =PaddedBlockCipherParameters<ParametersWithIV<KeyParameter>, KeyParameter>(ivParams, null);
    final PaddedBlockCipherImpl paddedCipher = PaddedBlockCipherImpl(PKCS7Padding(), cbcCipher);
    paddedCipher.init(true, paddingParams);

    try {
      
      return base64.encode(paddedCipher.process(Uint8List.fromList(data)));
    } catch (e) {
      return '';
    }
  }

  /// [_generateKey] Method
  /// Generates the key to Uint8List for encryption and description.
  static Uint8List _generateKey(String passphrase, Uint8List salt) {    
    Uint8List passphraseInt8List = Uint8List.fromList(passphrase.codeUnits);
    KeyDerivator derivator = PBKDF2KeyDerivator(HMac(SHA1Digest(), 64));    
    Pbkdf2Parameters params = Pbkdf2Parameters(salt, 65556, 32);            
    derivator.init(params);
    return derivator.process(passphraseInt8List);
  }

  
  static Uint8List generateRandomBytes(int numBytes) {
    if (_secureRandom == null) {
      _secureRandom = FortunaRandom();

      final seedSource = Random.secure();
      final seeds = <int>[];
      for (int i = 0; i < 32; i++) {
        seeds.add(seedSource.nextInt(256));
      }
      _secureRandom!.seed(KeyParameter(Uint8List.fromList(seeds)));
    }
    return _secureRandom!.nextBytes(numBytes);
  }
}

crypto_test.dart

import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';
import 'models/crypto.dart';

void main() {
    test('Descrypt Data', () async {
      if( kDebugMode ){    
        String cipherText = "2FA4qsjxXzk5kp6cnbv8QrlcKPyxO/PihUky8HVkNf2hRlIAq25yCc1RbidvM7chE7JzuZUuNLIeoiEKr+vWx4AhSQclh94iC4eZMIGjyFllOn8qZl2zM+cYMuVp0zS5klVIgefBDd+SJSvsIElCBIAmsnY=";
        final decryptToHuman = Crypto.decrypt( cipherText );
        print( decryptToHuman );
      }
    });

    test('Encrypt Data', () async {
      if( kDebugMode ){
        Map<String, dynamic> toCipherData = {
          'email': '[email protected]',
          'passowrd': '12345678'
        };
        final String json = jsonEncode( toCipherData );
        final cipherText = Crypto.encrypt( json );
        print( "Texto cifrado: $cipherText" );
      }
    });
}

错误调试控制台:

Invalid argument(s): Input data length must be a multiple of cipher's block size
PaddedBlockCipherImpl.process
package:pointycastle/padded_block_cipher/padded_block_cipher_impl.dart:60
Crypto.decrypt
test\…\models\crypto.dart:38
main.<fn>
test\…\crypto\encrypt_test.dart:10
2

✖ Descrypt Data
Exited (1)
flutter dart encryption pointycastle
2个回答
0
投票

我的问题就这样解决了。

感谢您的帮助。

在加密方法中

    Uint8List encryptedTextBytes = paddingCipher.process( plainTextBytes );
    final buffer = Uint8List(salt.length + iv.length + encryptedTextBytes.length);
    List.copyRange(buffer, 0, salt, 0, salt.length);
    List.copyRange(buffer, salt.length, iv, 0, iv.length);
    List.copyRange(buffer, salt.length+iv.length, encryptedTextBytes, 0, encryptedTextBytes.length);

0
投票

请您发送整个课程,我在运行您的代码时遇到一些错误

© www.soinside.com 2019 - 2024. All rights reserved.