encryptWithPlugin static method

  1. @protected
Future<SecretBox> encryptWithPlugin({
  1. required String name,
  2. required FlutterCipher cipher,
  3. Cipher? fallback,
  4. required List<int> clearText,
  5. required SecretKey secretKey,
  6. required List<int>? nonce,
  7. required List<int> aad,
})

Implementation

@protected
static Future<SecretBox> encryptWithPlugin({
  required String name,
  required FlutterCipher cipher,
  Cipher? fallback,
  required List<int> clearText,
  required SecretKey secretKey,
  required List<int>? nonce,
  required List<int> aad,
}) async {
  final secretKeyData = await secretKey.extractBytes();
  final secretKeyUint8List = asUint8List(secretKeyData);
  nonce ??= cipher.newNonce();
  final nonceUint8List = asUint8List(nonce);
  final aadUint8List = asUint8List(aad);

  if (secretKeyUint8List.length != cipher.secretKeyLength) {
    throw ArgumentError.value(
      secretKey,
      'secretKey',
      'Expected ${cipher.secretKeyLength} bytes, got ${secretKeyUint8List.length} bytes.',
    );
  }

  if (nonce.length != cipher.nonceLength) {
    throw ArgumentError.value(
      nonce,
      'nonce',
      'Expected ${cipher.nonceLength} bytes, got ${nonce.length} bytes.',
    );
  }

  final macAlgorithm = cipher.macAlgorithm;
  if (aad.isNotEmpty && !macAlgorithm.supportsAad) {
    throw ArgumentError(
      'AAD is not supported by $macAlgorithm, but parameter `aad` is non-empty.',
    );
  }

  final clearTextSize = clearText.length;
  final lock = CryptographyChannelQueue.defaultInstance.newLock(
    size: clearTextSize,
  );
  await lock.lock();
  Map result;
  try {
    final clearTextUint8List = asUint8List(clearText);
    result = await invokeMethod(
      'encrypt',
      {
        'algo': name,
        'data': clearTextUint8List,
        'key': secretKeyUint8List,
        'nonce': nonceUint8List,
        'aad': aadUint8List,
      },
      useQueue: false, // We do queueing ourselves
    );
  } on UnsupportedError {
    if (fallback == null) {
      rethrow;
    }
    return fallback.encrypt(
      clearText,
      secretKey: secretKey,
      nonce: nonce,
      aad: aad,
    );
  } finally {
    lock.unlock();
  }

  final cipherText = result['cipherText'] as Uint8List;

  // Sanity check
  if (cipherText.length != cipher.cipherTextLength(clearTextSize)) {
    throw StateError(
      '${cipher.runtimeType}.encrypt sanity check failed: '
      'cipherText.length (${cipherText.length}) != '
      'clearText.length (size})',
    );
  }

  final macBytes = result['mac'] as Uint8List;
  return SecretBox(
    cipherText,
    nonce: nonce,
    mac: Mac(macBytes),
  );
}