import 'dart:async'; import 'dart:typed_data'; import 'dart:js_util' as jsutil; import 'dart:html' as html; import 'package:js/js.dart'; @JS('Promise') class Promise { external factory Promise._(); } @JS('Algorithm') class Algorithm { external String get name; } @JS('crypto.subtle.encrypt') external Promise encrypt( dynamic algorithm, html.CryptoKey key, ByteBuffer data, ); @JS('crypto.subtle.decrypt') external Promise decrypt( dynamic algorithm, html.CryptoKey key, ByteBuffer data, ); @JS() @anonymous class AesGcmParams { external factory AesGcmParams({ required String name, required ByteBuffer iv, ByteBuffer? additionalData, int tagLength = 128, }); } ByteBuffer jsArrayBufferFrom(List data) { // Avoid copying if possible if (data is Uint8List && data.offsetInBytes == 0 && data.lengthInBytes == data.buffer.lengthInBytes) { return data.buffer; } // Copy return Uint8List.fromList(data).buffer; } @JS('crypto.subtle.importKey') external Promise importKey( String format, ByteBuffer keyData, dynamic algorithm, bool extractable, List keyUsages, ); @JS('crypto.subtle.exportKey') external Promise exportKey( String format, html.CryptoKey key, ); @JS('crypto.subtle.deriveKey') external Promise deriveKey( dynamic algorithm, html.CryptoKey baseKey, dynamic derivedKeyAlgorithm, bool extractable, List keyUsages); @JS('crypto.subtle.deriveBits') external Promise deriveBits( dynamic algorithm, html.CryptoKey baseKey, int length, ); Future impportKeyFromRawData(List secretKeyData, {required String webCryptoAlgorithm, required List keyUsages}) async { return jsutil.promiseToFuture(importKey( 'raw', jsArrayBufferFrom(secretKeyData), jsutil.jsify({'name': webCryptoAlgorithm}), false, keyUsages, )); }