Dart/Flutter 中的 AES/GCM/NoPadding 加解密

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

我想在我的Flutter应用程序中应用AES/GCM/NoPadding加密和解密

用例:我将加密一些字符串并将其发送到服务器,服务器将解密并处理它并向我发送更新的加密数据,然后我将再次解密它以处理它。

我尝试探索 cryptographycryptography_flutterencryptpointycastle

但没有找到任何明确的文档,我可以在其中应用 AES/GCM/NoPadding 进行加密。 我无法应用 AES/CBC/PKCS5PADDING 或 AES/CBC/PKCS7PADDING,因为该点卡在 APPSEC 下。

任何人都可以帮助我如何在 Flutter/Dart 中执行 AES/GCM/NoPadding 加密和解密。

提前致谢。

flutter dart encryption aes aes-gcm
1个回答
0
投票

这是在 Dart/Flutter 中使用 PointyCastle 进行的简单字符串加密(和解密)。正如@Topaco 所评论的,您应该考虑使用像 PBKDF2 这样的安全密钥派生。

编辑:此代码是“跨平台密码学”项目的一部分。主要目的是展示像 AES-GCM 这样的算法如何在不同的语言中运行。因此,我使用固定的输入参数和输出,这些参数和输出可能不会在实际项目中使用。

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

main() {
/* add in pubspec.yaml:
dependencies:
  pointycastle: ^3.1.1
 */

  printC('AES GCM 256 String encryption with random key');
  final plaintext = 'The quick brown fox jumps over the lazy dog';
  printC('plaintext: ' + plaintext);

  // generate random key
  var encryptionKey = generateRandomAesKey();
  var encryptionKeyBase64 = base64Encoding(encryptionKey);
  printC('encryptionKey (Base64): ' + encryptionKeyBase64);

  // encryption
  printC('\n* * * Encryption * * *');
  String ciphertextBase64 = aesGcmEncryptionToBase64(encryptionKey, plaintext);
  printC('ciphertext (Base64): ' + ciphertextBase64);
  printC('output is (Base64) nonce : (Base64) ciphertext : (Base64) gcmTag');

  printC('\n* * * Decryption * * *');
  var ciphertextDecryptionBase64 = ciphertextBase64;
  printC('ciphertext (Base64): ' + ciphertextDecryptionBase64);
  printC('input is (Base64) nonce : (Base64) ciphertext : (Base64) gcmTag');
  var decryptedtext = aesGcmDecryptionFromBase64(encryptionKey, ciphertextDecryptionBase64);
  printC('plaintext:  ' + decryptedtext);
}

String aesGcmEncryptionToBase64(Uint8List key, String plaintext) {
  var plaintextUint8 = createUint8ListFromString(plaintext);
  final nonce = generateRandomNonce();
  final cipher = GCMBlockCipher(AESFastEngine());
  var aeadParameters = AEADParameters(KeyParameter(key), 128, nonce, Uint8List(0));
  cipher.init(true, aeadParameters);
  var ciphertextWithTag = cipher.process(plaintextUint8);
  var ciphertextWithTagLength = ciphertextWithTag.lengthInBytes;
  var ciphertextLength = ciphertextWithTagLength - 16; // 16 bytes = 128 bit tag length
  var ciphertext = Uint8List.sublistView(ciphertextWithTag, 0, ciphertextLength);
  var gcmTag = Uint8List.sublistView(ciphertextWithTag, ciphertextLength, ciphertextWithTagLength);
  final nonceBase64 = base64.encode(nonce);
  final ciphertextBase64 = base64.encode(ciphertext);
  final gcmTagBase64 = base64.encode(gcmTag);
  return nonceBase64 + ':' + ciphertextBase64 + ':' + gcmTagBase64;
}

String aesGcmDecryptionFromBase64(Uint8List key, String data) {
  var parts = data.split(':');
  var nonce = base64.decode(parts[0]);
  var ciphertext = base64.decode(parts[1]);
  var gcmTag = base64.decode(parts[2]);
  var bb = BytesBuilder();
  bb.add(ciphertext);
  bb.add(gcmTag);
  var ciphertextWithTag = bb.toBytes();
  final cipher = GCMBlockCipher(AESFastEngine());
  var aeadParameters = AEADParameters(KeyParameter(key), 128, nonce, Uint8List(0));
  cipher.init(false, aeadParameters);
  return new String.fromCharCodes(cipher.process(ciphertextWithTag));
}

Uint8List generateRandomAesKey() {
  final _sGen = Random.secure();
  final _seed =
  Uint8List.fromList(List.generate(32, (n) => _sGen.nextInt(255)));
  SecureRandom sec = SecureRandom("Fortuna")..seed(KeyParameter(_seed));
  return sec.nextBytes(32);
}

Uint8List generateRandomNonce() {
  final _sGen = Random.secure();
  final _seed =
  Uint8List.fromList(List.generate(32, (n) => _sGen.nextInt(255)));
  SecureRandom sec = SecureRandom("Fortuna")..seed(KeyParameter(_seed));
  return sec.nextBytes(12);
}

Uint8List createUint8ListFromString(String s) {
  var ret = new Uint8List(s.length);
  for (var i = 0; i < s.length; i++) {
    ret[i] = s.codeUnitAt(i);
  }
  return ret;
}

String base64Encoding(Uint8List input) {
  return base64.encode(input);
}

Uint8List base64Decoding(String input) {
  return base64.decode(input);
}

void printC(String newString) {
  // for compatibility reasons to FlutterEmptyConsole
  print(newString);
}
© www.soinside.com 2019 - 2024. All rights reserved.