google / google/webcrypto.dart
bug: browser JWK exports omit use metadata emitted by the native backend
- Dominant language
- Dart
- Stars
- 116
- Forks
- 110
- Avg merge
- 6d 8h
- Merged PRs (30d)
- 9
Description
## Description
`exportJsonWebKey()` produces different JWK metadata depending on the backend.
The native FFI backend adds an algorithm-appropriate `use` value:
- `"enc"` for encryption algorithms such as AES-GCM
- `"sig"` for signing algorithms such as HMAC
The browser backend delegates to `SubtleCrypto.exportKey()`, removes `key_ops` and `ext`, and returns the result without adding `use`. Consequently, the same public API returns different JWK shapes on native and browser platforms.
Both outputs are valid JWKs because `use` is optional, but the backend-dependent result is observable and can break applications that persist, compare, validate, or route exported keys using this metadata.
## Reproduction
```dart
import 'dart:typed_data';
import 'package:webcrypto/webcrypto.dart';
Future main() async {
final aes = await AesGcmSecretKey.importRawKey(Uint8List(16));
final hmac = await HmacSecretKey.importRawKey(
Uint8List(32),
Hash.sha256,
);
print(await aes.exportJsonWebKey());
print(await hmac.exportJsonWebKey());
}
```
Native output includes:
```text
{kty: oct, use: enc, alg: A128GCM, ...}
{kty: oct, use: sig, alg: HS256, ...}
```
Chrome output under both Dart2JS and Dart2Wasm omits `use`:
```text
{kty: oct, alg: A128GCM, ...}
{kty: oct, alg: HS256, ...}
```
## Expected behavior
`exportJsonWebKey()` should return consistent algorithm metadata across supported backends.
## Suggested fix
Normalize browser JWK exports after `SubtleCrypto.exportKey()`:
- add `"use": "enc"` for AES and RSA-OAEP keys;
- add `"use": "sig"` for HMAC, ECDSA, RSA-PSS, and RSASSA-PKCS1-v1_5 keys;
- continue omitting `use` for ECDH;
- continue omitting `key_ops` and `ext`, since configurable key capabilities are outside the current public API;
- add regression coverage for native, Dart2JS, and Dart2Wasm.
Contributor guide
Research direction
Start at the browser backend's exportJsonWebKey() entry point and inspect how the result from SubtleCrypto.exportKey() is normalized, then compare it with the native backend behavior. Add the algorithm-specific use metadata described in the issue while preserving the existing key_ops, ext, and ECDH behavior, and add regression coverage for native, Dart2JS, and Dart2Wasm.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- dart
- Domain
- cryptography, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 70/100