google / google/webcrypto.dart

bug: browser JWK exports omit use metadata emitted by the native backend

Open
#399 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.