Does crypto.subtle.deriveKey in Firefox ignore the length parameter: browser bug or implementation error?
When using the Web Crypto API to generate a shared secret from a 128-bit X25519 key pair for AES-128, I’ve observed different browser behaviors:
- Google Chrome: correctly generates a 128-bit key according to the length parameter
- Mozilla Firefox: ignores the length parameter, always creating a 256-bit key
Is this a known Firefox bug, or am I making an error in using the Web Crypto API functions?
Additional details:
- When using deriveBits instead of deriveKey, the behavior is correct in both browsers
- When using the ECDH algorithm instead of X25519, it also works properly
- Reproduction code is available on Codepen
There is indeed a known issue in Firefox with the length parameter in the crypto.subtle.deriveKey function when using the X25519 algorithm - this is a browser implementation bug. When using X25519, Firefox ignores the specified key length and always generates a 256-bit key, while Chrome correctly handles the length parameter.
Contents
- Problem Description
- Technical Implementation Details
- Comparison with Other Algorithms
- Workarounds
- Bug Status
- Usage Recommendations
Problem Description
In Firefox, when using crypto.subtle.deriveKey with the X25519 algorithm, the length parameter is ignored, resulting in the creation of fixed-length 256-bit keys. This behavior differs from other browsers and the Web Crypto API specification.
As shown in bug report 1922522, Mozilla developers acknowledge this issue. The discussion indicates that for ECDH and X25519 algorithms, special behavior for the length parameter should be followed, but the current implementation in Firefox does not meet these requirements.
Technical Implementation Details
The issue only manifests when using the deriveKey function with X25519. As you correctly noted:
- deriveBits: works correctly in both browsers
- ECDH: works correctly in Firefox
- X25519 + deriveKey: ignores the
lengthparameter in Firefox
According to MDN documentation, when no key length is explicitly specified for HMAC algorithms, Firefox defaults to the hash function’s block size (256 bits for SHA-256). However, the problem is that even when explicitly specifying the key length, Firefox continues to ignore this parameter for X25519.
Comparison with Other Algorithms
| Algorithm | Function | Firefox Behavior | Chrome Behavior |
|---|---|---|---|
| X25519 | deriveKey | Ignores length | Respects length |
| X25519 | deriveBits | Respects length | Respects length |
| ECDH | deriveKey | Respects length | Respects length |
| ECDH | deriveBits | Respects length | Respects length |
This confirms that the issue is specific to the X25519 + deriveKey combination in Firefox.
Workarounds
There are several ways to work around this issue:
- Using deriveBits + importKey:
// Instead of deriveKey, we use deriveBits
const derivedBits = await crypto.subtle.deriveBits(
{ name: 'X25519', public: publicKey },
privateKey,
128 // length in bits
);
// Then import the result as a key
const derivedKey = await crypto.subtle.importKey(
'raw',
derivedBits,
{ name: 'AES-GCM' },
false,
['encrypt', 'decrypt']
);
- Using ECDH instead of X25519:
// If possible, use ECDH
const keyPair = await crypto.subtle.generateKey(
{ name: 'ECDH', namedCurve: 'P-256' },
false,
['deriveKey', 'deriveBits']
);
- Checking the browser and using an alternative approach:
const isFirefox = navigator.userAgent.indexOf('Firefox') > -1;
if (isFirefox && algorithm.name === 'X25519') {
// Use the workaround for Firefox
} else {
// Normal behavior for other browsers
}
Bug Status
The issue is actively being discussed in the Mozilla community. In report 1804788, support for X25519 in Firefox is mentioned, but not specifically regarding the length parameter issue.
In report 1922522, the behavior of the length parameter for ECDH and X25519 is detailed, where it’s noted that a zero length value should return an empty string, which is also not correctly implemented in Firefox.
Mozilla developers are considering revising the approach to the Web Crypto API, as mentioned in standard positions, where they acknowledge that the current API design was too “secure” and requires fixes.
Usage Recommendations
- For critical applications: Use the
deriveBits+importKeycombination as a temporary solution - For cross-browser compatibility: Always test in Firefox and use workarounds if necessary
- Monitor bug status: Follow updates in Bugzilla for information on fixes
- Alternative algorithms: If possible, consider using ECDH with P-256/P-384 curves as a replacement for X25519
The issue is confirmed in several Firefox versions and is a known implementation bug, not an error in your code. Your use of the API was correct - indeed Firefox demonstrates incompatible behavior with other browsers and the specification.
Sources
- Bug 1922522 - ECDH and X25519 derive bits should return an empty string when length is zero
- Bug 1804788 - Support for Curve25519 in the Web Crypto API: Ed25519 algorithm
- MDN: SubtleCrypto.deriveKey()
- MDN: EcdhKeyDeriveParams
- GitHub: X25519 in Web Cryptography
- Stack Overflow: How to set the out-length with the Web Crypto API SubtleCrypto.deriveKey() for PBKDF2
Conclusion
- Firefox indeed has a known bug with the
lengthparameter inderiveKeyfor X25519 - This is confirmed by multiple bug reports in Mozilla Bugzilla
- Your code was correct - the issue is in the browser implementation
- Use the
deriveBits+importKeycombination as a temporary solution - Monitor bug status updates for information on fixes
- Consider alternative algorithms for cross-browser compatibility