81 lines
1.9 KiB
Dart
81 lines
1.9 KiB
Dart
// Author: Hugo Pointcheval
|
|
// Email: git@pcl.ovh
|
|
// -----
|
|
// File: aes_gcm.dart
|
|
// Created Date: 24/05/2022 16:34:54
|
|
// Last Modified: 27/05/2022 17:36:31
|
|
// -----
|
|
// Copyright (c) 2022
|
|
|
|
// ignore_for_file: implementation_imports
|
|
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:pointycastle/export.dart';
|
|
import 'package:pointycastle/src/platform_check/platform_check.dart';
|
|
|
|
class AesGcm {
|
|
FortunaRandom? _secureRandom;
|
|
|
|
Uint8List encrypt(Uint8List data, Uint8List key) {
|
|
final iv = generateRandomBytes(12);
|
|
|
|
final gcm = GCMBlockCipher(AESEngine())
|
|
..init(
|
|
true,
|
|
AEADParameters(
|
|
KeyParameter(key),
|
|
16 * 8,
|
|
iv!,
|
|
Uint8List(0),
|
|
),
|
|
); // true=encrypt
|
|
|
|
final cipherText = gcm.process(data);
|
|
|
|
return Uint8List.fromList(
|
|
iv + cipherText,
|
|
);
|
|
}
|
|
|
|
Uint8List decrypt(Uint8List cipherText, Uint8List key) {
|
|
final iv = Uint8List.fromList(cipherText.sublist(0, 12));
|
|
final cipherTextWithoutIv = Uint8List.fromList(
|
|
cipherText.sublist(12),
|
|
);
|
|
|
|
final gcm = GCMBlockCipher(AESEngine())
|
|
..init(
|
|
false,
|
|
AEADParameters(
|
|
KeyParameter(key),
|
|
16 * 8,
|
|
iv,
|
|
Uint8List(0),
|
|
),
|
|
); // false=decrypt
|
|
|
|
// Decrypt the cipherText block-by-block
|
|
|
|
final paddedPlainText = gcm.process(cipherTextWithoutIv);
|
|
|
|
return paddedPlainText;
|
|
}
|
|
|
|
/// Generate random bytes to use as the Initialization Vector (IV).
|
|
Uint8List? generateRandomBytes(int numBytes) {
|
|
if (_secureRandom == null) {
|
|
// First invocation: create _secureRandom and seed it
|
|
|
|
_secureRandom = FortunaRandom();
|
|
_secureRandom!.seed(
|
|
KeyParameter(Platform.instance.platformEntropySource().getBytes(32)));
|
|
}
|
|
|
|
// Use it to generate the random bytes
|
|
|
|
final iv = _secureRandom!.nextBytes(numBytes);
|
|
return iv;
|
|
}
|
|
}
|