The web crypto API defines two different KDF utilities, namely deriveBits
and deriveKey
. While the former allows you to specify the desired output length (RFC 5869 calls this parameter L
), the latter doesn’t seem to do so.
I need to use HKDF with SHA-512 (as the spec I’m implementing requires this) in order to derive an HMAC-SHA256 key. In other words, 256 output bits are sufficient; but only deriveBits
seems to have a corresponding parameter:
const baseKey = await crypto.subtle.importKey('raw', new Uint8Array(32), { name: 'HKDF' }, false, ['deriveKey', 'deriveBits'])
const salt = new Uint8Array(16)
const info = new Uint8Array(8)
// deriveBits → derives 256 bit:
const rawHmacKey1 = await crypto.subtle.deriveBits({ name: 'HKDF', hash: 'SHA-512', salt: salt, info: info }, baseKey, 256);
const hmacKey1 = await crypto.subtle.importKey('raw', rawHmacKey1, { name: 'HMAC', hash: 'SHA-256' }, true, ['sign']);
const exported1 = new Uint8Array(await crypto.subtle.exportKey('raw', hmacKey1));
console.log(btoa(exported1)) // MTgxLDEyLDgsMTExLDI3LDI0OCw4NSw3OCw0MywxMCw5MywyNDIsMTksMTg5LDE5MSwxNzMsMTM2LDEwMCwyMSwyMjcsMzksMTI2LDE3OSwxOTYsNTAsODYsNjEsMjcsMTQzLDIxMiwxOTksMjAz
// deriveKey → derives 512 bit:
const hmacKey2 = await crypto.subtle.deriveKey({ name: 'HKDF', hash: 'SHA-512', salt: salt, info: info }, baseKey, { name: 'HMAC', hash: 'SHA-256' }, true, ['sign']);
const exported2 = new Uint8Array(await crypto.subtle.exportKey('raw', hmacKey2));
console.log(btoa(exported2)) // MTgxLDEyLDgsMTExLDI3LDI0OCw4NSw3OCw0MywxMCw5MywyNDIsMTksMTg5LDE5MSwxNzMsMTM2LDEwMCwyMSwyMjcsMzksMTI2LDE3OSwxOTYsNTAsODYsNjEsMjcsMTQzLDIxMiwxOTksMjAzLDUwLDE4Myw3Miw4OSwyMDQsMTcsMzksMTY5LDE4OCw5Niw3NSw5NSwxMTMsMjQ3LDExNywxOTQsNDYsMTY0LDIyOSwyMTMsNzUsMjE5LDI0NCwyMjYsMjAwLDE2MCw5NCwxNCw3MiwxNjMsMTcwLDEwMg==
Note that when using deriveKey
I explicitly specified { name: 'HMAC', hash: 'SHA-256' }
as key usage parameter. Regardless the derived key length seems to solely depend on the specified hash algorithm (SHA-512
→ 64 bytes).
As I would prefer to use deriveKey
, my question is: How do I specify the desired output key size?