google / webcrypto.dart

Cross-platform implementation of Web Cryptography APIs
https://pub.dev/packages/webcrypto
Apache License 2.0
81 stars 46 forks source link

Null check error in web worker when using `RsaOaepPrivateKey.importPkcs8Key` for RSA decryption #149

Closed chaudharydeepanshu closed 3 weeks ago

chaudharydeepanshu commented 1 month ago

Description

I'm using this package for RSA decryption in both isolates and web workers. While it works fine in isolates, I encounter a null check error when running in a web worker.

Code

This is the function that runs for decryption:

import 'dart:convert';
import 'package:encrypt/encrypt.dart';
import 'package:webcrypto/webcrypto.dart';
import 'package:pem/pem.dart';
import 'package:basic_utils/basic_utils.dart';

Future<String> decryptDEKWeb({
  required String encryptedDek,
  required String rsaPrivateKeyPKCS1,
}) async {
  // Get RSAPrivateKey from the rsaPrivateKeyPKCS1
  final rSAPrivateKey =
  RSAKeyParser().parse(rsaPrivateKeyPKCS1) as RSAPrivateKey;

  // Get PKCS#8 from RSAPrivateKey
  String pkcs8 = CryptoUtils.encodeRSAPrivateKeyToPem(rSAPrivateKey);

  // Decode PKCS#8 key to get key data
  List<int> keyData = PemCodec(PemLabel.privateKey).decode(pkcs8);

  // Import key data as a private key
  final privateKey = await RsaOaepPrivateKey.importPkcs8Key(keyData, Hash.sha1);

  if (encryptedDek.startsWith('encRsa_')) {
    final encryptedData = base64.decode(encryptedDek.substring(7));

    // Decrypt the encrypted data
    final decryptedBytes = await privateKey.decryptBytes(encryptedData);

    return base64.encode(decryptedBytes);
  } else {
    throw ('Invalid encrypted dek');
  }
}

Error

This is the error I get in the web worker:

[   +1 ms] RethrownDartError: Null check operator used on a null value

           dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 329:10  createErrorWithStack
           dart-sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart 265:28            _throw
           dart-sdk/lib/core/errors.dart 120:5                                           throwWithStackTrace
           dart-sdk/lib/async/zone.dart 1386:11                                          callback
           dart-sdk/lib/async/schedule_microtask.dart 40:11                              _microtaskLoop
           dart-sdk/lib/async/schedule_microtask.dart 49:5                               _startMicrotaskLoop
           dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 181:7            <fn>

From what I can tell, the error is being thrown on this line:

final privateKey = await RsaOaepPrivateKey.importPkcs8Key(keyData, Hash.sha1);

Environment

Steps to Reproduce

  1. Run the provided decryptDEKWeb function inside a web worker environment.
  2. Observe the null check error when calling RsaOaepPrivateKey.importPkcs8Key.

Expected Behavior

The function should successfully import the private key and decrypt the data, as it does in an isolate.

Additional Information

Let me know if any further details are required for debugging.

jonasfj commented 1 month ago

Please provide a gist with all the code your running.

A script that shows how to compile it.

And how to open it in a browser AND what browser!


Do not that WebCrypto only works in https://, so if you're opening it as a file or opening it on localhost it shouldn't work.

image

image

I've occasionally done such setups locally with ngrok, come to think of it I'm actually surprised our integration tests work in all browsers -- I think those just load from localhost, but maybe package:test does some magic :rofl:

chaudharydeepanshu commented 1 month ago

Please provide a gist with all the code your running.

A script that shows how to compile it.

And how to open it in a browser AND what browser!

I'll soon add a small example app to recreate the issue.

Do not that WebCrypto only works in https://

Btw, this secure content requirement is weird because I was running the app on localhost without using a web worker and it worked fine. Does the secure content requirement only apply when I run it inside web workers?

Thanks for the response!

jonasfj commented 3 weeks ago

Does the secure content requirement only apply when I run it inside web workers?

Don't know this might differ from browser to browser, and can probably be disabled when starting the browser.

If you're interested in documenting when this works, we're happy to take a PR another bullet point to the compatibility notes in the README.

Otherwise, I think we consider this outside the scope of this package. We offer what the browser offers.

Filed https://github.com/google/webcrypto.dart/issues/159