@nfen/webcrypto-ts
Version:
Enforced Webcrypto wrapper
144 lines • 4.29 kB
JavaScript
/**
* Code related to HKDF
* @module
*/
import { handler as AesCbcHandler } from "../aes/aes_cbc.js";
import { handler as AesCtrHandler } from "../aes/aes_ctr.js";
import { handler as AesGcmHandler } from "../aes/aes_gcm.js";
import { handler as AesKwHandler } from "../aes/aes_kw.js";
import { Alg as AesAlg, } from "../aes/shared.js";
import { Alg as HmacAlg, handler as hmacHandler, } from "../hmac/index.js";
import * as proxy from "../proxy.js";
import { Alg, KdfShared, } from "./shared.js";
const handler = {
get(target, prop) {
switch (prop) {
case "self":
return target;
case "deriveKey":
return (algorithm, derivedKeyType, extractable, keyUsages) => deriveKey(algorithm, target, derivedKeyType, extractable, keyUsages);
case "deriveBits":
return (algorithm, length) => deriveBits(algorithm, target, length);
}
return Reflect.get(target, prop);
},
};
/**
* Generate key material for deriving
* @example
* ```ts
* const keyMaterial = await HKDF.generateKeyMaterial("raw", new TextEncoder().encode("lots_of_entropy"));
* ```
*/
export const generateKeyMaterial = async (format, key, extractable) => {
const keyMaterial = await KdfShared.generateKeyMaterial(format, key, Alg.Variant.HKDF, extractable);
return proxy.proxifyKey(handler)(keyMaterial);
};
/**
* Derive a shared key from HKDF key material
* @example
* ```ts
* const hmacParams: params.EnforcedHmacKeyGenParams = {
* name: Authentication.Alg.Code.HMAC,
* hash: SHA.Alg.Variant.SHA_512,
* length: 512,
* };
* const salt = await Random.Salt.generate();
* const info = await Random.getValues(6);
* let key = await HKDF.deriveKey(
* { salt, info, hash: "SHA-512" },
* keyMaterial,
* hmacParams
* );
* ```
* @example
* ```ts
* const hmacParams: params.EnforcedHmacKeyGenParams = {
* name: Authentication.Alg.Code.HMAC,
* hash: SHA.Alg.Variant.SHA_512,
* length: 512,
* };
* const salt = await Random.Salt.generate();
* const info = await Random.getValues(6);
* let key = await keyMaterial.deriveKey(
* { salt, info, hash: "SHA-512" },
* hmacParams
* );
* ```
* @example
* ```ts
* const keyMaterial = await HKDF.generateKeyMaterial(
* "raw",
* await Random.getValues(16)
* );
* let key = await HKDF.deriveKey(
* {
* hash: "SHA-256",
* salt,
* },
* keyMaterial.self,
* {
* name: "AES-GCM",
* length: 256,
* }
* );
* ```
* @example
* ```ts
* const key = await keyMaterial.deriveKey(
* {
* hash: "SHA-256",
* salt,
* },
* {
* name: "AES-GCM",
* length: 256,
* }
* );
*/
export const deriveKey = async (algorithm, baseKey, derivedKeyType, extractable, keyUsages) => {
const derived = await KdfShared.deriveKey({
...algorithm,
name: Alg.Variant.HKDF,
}, baseKey, derivedKeyType, extractable, keyUsages);
switch (derivedKeyType.name) {
case HmacAlg.Code.HMAC:
return proxy.proxifyKey(hmacHandler)(derived);
case AesAlg.Mode.AES_CBC:
return proxy.proxifyKey(AesCbcHandler)(derived);
case AesAlg.Mode.AES_CTR:
return proxy.proxifyKey(AesCtrHandler)(derived);
case AesAlg.Mode.AES_GCM:
return proxy.proxifyKey(AesGcmHandler)(derived);
case AesAlg.Mode.AES_KW:
return proxy.proxifyKey(AesKwHandler)(derived);
}
throw new Error("Invalid alg");
};
/**
* Derive a number bits with a given key material
* @example
* ```ts
* const salt = await Random.Salt.generate();
* const info = await Random.getValues(6);
* const bits = await HKDF.deriveBits(
* { salt, info, hash: "SHA-512" },
* keyMaterial,
* 128
* );
* ```
* @example
* ```ts
* const salt = await Random.Salt.generate();
* const info = await Random.getValues(6);
* const bits = await keyMaterial.deriveBits(
* { salt, info, hash: "SHA-512" },
* 128
* );
* ```
*/
export const deriveBits = (algorithm, baseKey, length) => KdfShared.deriveBits({
...algorithm,
name: Alg.Variant.HKDF,
}, baseKey, length);
//# sourceMappingURL=hkdf.js.map