Null check error in web worker when using `RsaOaepPrivateKey.importPkcs8Key` for RSA decryption
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
- The code runs fine in isolates, but throws this error when used in a web worker.
- The web worker code is generated using isolate_manager with the following command:
dart run isolate_manager:generate
Steps to Reproduce
- Run the provided
decryptDEKWebfunction inside a web worker environment. - 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
- The
keyDatapassed toimportPkcs8Keyis valid, as confirmed by logging it before the function call. - This issue seems specific to web workers, as the same code works without issues outside of web worker.
Let me know if any further details are required for debugging.
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.
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:
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!
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