Search code examples
typescriptflutterdartcryptographysubtlecrypto

Crypto.subtle in Dart?


Is there any package or utilities related to crypto.subtle present in Dart? I found this but I believe that's read-only, not accessible and for browsers only.

I am looking for something similar for this piece of code in dart

 static async CbcEncrypt(data: Uint8Array, iv: Uint8Array, key: Uint8Array): Promise<Uint8Array> {
    const importedKey = await crypto.subtle.importKey(
      'raw',
      key,
      {
        //this is the algorithm options
        name: 'AES-CBC',
      },
      false, //whether the key is extractable (i.e. can be used in exportKey)
      ['encrypt', 'decrypt'] //can be "encrypt", "decrypt", "wrapKey", or "unwrapKey"
    );

    const cipher = await crypto.subtle.encrypt(
      {
        name: 'AES-CBC',
        iv: iv,
      },
      importedKey, //from generateKey or importKey above
      data //ArrayBuffer of data you want to encrypt
    );

    return new Uint8Array(cipher);
  }

I looked at various packages crypto, webcrypto, cryptography but I couldn't relate anything to the code above.

I did find a package pointycastle that looked promising. Is this thing could be a similar to crypto.subtle ??

Or Is it possible to get access to the brower's crypto.subtle object / API from Dart?


Solution

  • Simply:

    import 'package:webcrypto/webcrypto.dart';
    
    Future<List<int>> cbcEncrypt(
      List<int> data,
      List<int> iv,
      List<int> key
    ) async {
      final key = await AesCbcSecretKey.importRawKey(key);
      final ciphertext = await key.encryptBytes(data, iv);
      return ciphertext;
    }
    

    But I'm also author of package:webcrypto :D

    There is no concept of extractable or usages in package:webcrypto. You can just wrap the object if you need to forbid such things (or maybe we'll add it in the future). There is also no wrap/unwrap/derive key support in package:webcrypto, but you can simply export a raw key and encrypt/decrypt or a do deriveBits and pass the derived bits to import raw key (this is the same that the window.subtle APIs do.


    Tip: methods in package:webcrypto that returns bytes always return Uint8List which implements List<int>. You'll get slightly faster operations by only passing around Uint8List. But other APIs working with bytes in Dart pass around List<int>, so package:webcrypto accepts it as input.