@nfen/webcrypto-ts
Version:
Enforced Webcrypto wrapper
149 lines • 4.24 kB
JavaScript
/**
* Code related to PBKDF2
* @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);
},
};
const hashIterations = {
"SHA-1": 1300000,
"SHA-256": 600000,
"SHA-384": 600000,
"SHA-512": 210000,
};
/**
* Generate key material for deriving
* @example
* ```ts
* const keyMaterial = await PBKDF2.generateKeyMaterial("raw", new TextEncoder().encode("could_be_a_little_entropy"));
* ```
*/
export const generateKeyMaterial = async (format, key, extractable) => {
const keyMaterial = await KdfShared.generateKeyMaterial(format, key, Alg.Variant.PBKDF2, extractable);
return proxy.proxifyKey(handler)(keyMaterial);
};
/**
* Derive a shared key from PBKDF2 key material
* @example
* ```ts
* const hmacParams: params.EnforcedHmacKeyGenParams = {
* name: Authentication.Alg.Code.HMAC,
* hash: SHA.Alg.Variant.SHA_512,
* length: 512,
* };
* let key = await PBKDF2.deriveKey(
* { hash: "SHA512" },
* keyMaterial,
* hmacParams
* );
* ```
* @example
* ```ts
* const hmacParams: params.EnforcedHmacKeyGenParams = {
* name: Authentication.Alg.Code.HMAC,
* hash: SHA.Alg.Variant.SHA_512,
* length: 512,
* };
* const keyMaterial = await PBKDF2.generateKeyMaterial(
* "raw",
* await Random.getValues(16)
* );
* let key = await keyMaterial.deriveKey(
* { hash: "SHA512" },
* hmacParams
* );
* ```
* @example
* ```ts
* const keyMaterial = await PBKDF2.generateKeyMaterial(
* "raw",
* await Random.getValues(16)
* );
* let key = await PBKDF2.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.PBKDF2,
iterations: hashIterations[algorithm.hash],
}, 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 bits = await PBKDF2.deriveBits(
* { hash: "SHA-512" },
* keyMaterial,
* 128
* );
* ```
* @example
* ```ts
* const bits = await keyMaterial.deriveBits(
* { hash: "SHA-512" },
* 128
* );
* ```
*/
export const deriveBits = (algorithm, baseKey, length) => KdfShared.deriveBits({
...algorithm,
name: Alg.Variant.PBKDF2,
iterations: hashIterations[algorithm.hash],
}, baseKey, length);
//# sourceMappingURL=pbkdf.js.map