mima-kit
Version:
mima-kit is a cryptographic suite implemented in TypeScript. The goal is to provide an easy-to-use cryptographic library. mima-kit 是一个使用 TypeScript 实现的密码学套件。目标是提供一个简单易用的密码学库。
72 lines (71 loc) • 2.85 kB
JavaScript
import { Counter, joinBuffer } from './utils';
/**
* ANSI-X9.63 Key Derivation Function
*
* ANSI-X9.63 密钥派生函数
*/
export function x963kdf(hash) {
const d_bit = hash.DIGEST_SIZE << 3;
return (k_bit, ikm, info = new Uint8Array(0)) => {
/** Output Keying Material */
const okm = [];
const counter = new Counter([0, 0, 0, 1]);
for (let okm_bit = 0; okm_bit < k_bit; okm_bit += d_bit) {
const data = joinBuffer(ikm, counter, info);
okm.push(hash(data));
counter.inc();
}
return joinBuffer(...okm).slice(0, k_bit >> 3);
};
}
/**
* HMAC-based Key Derivation Function (HKDF), please combine `hmac` and `hash` externally to control the behavior of calling `hmac` inside the function.
*
* 基于 HMAC 的密钥派生函数 (HKDF), 请在外部组合 `hmac` 和 `hash` 函数, 以控制在函数内部调用 `hmac` 时的行为.
*/
export function hkdf(k_hash, salt = new Uint8Array(k_hash.DIGEST_SIZE)) {
const d_bit = k_hash.DIGEST_SIZE << 3;
return (k_bit, ikm, info = new Uint8Array(0)) => {
/** Pseudo-Random Key */
const prk = k_hash(salt, ikm);
/** Output Keying Material */
const okm = [];
const counter = new Uint8Array([1]);
let prv = new Uint8Array(0);
for (let okm_bit = 0; okm_bit < k_bit; okm_bit += d_bit) {
prv = k_hash(prk, joinBuffer(prv, info, counter));
okm.push(prv);
counter[0]++;
}
return joinBuffer(...okm).slice(0, k_bit >> 3);
};
}
/**
* Password-Based Key Derivation Function 2 (PBKDF2), please combine `hmac` and `hash` externally to control the behavior of calling `hmac` inside the function.
* Also, PBKDF2 does not use the `info` parameter, if provided, it will be ignored.
*
* PBKDF2 密码基础密钥派生函数 (PBKDF2), 请在外部组合 `hmac` 和 `hash` 函数, 以控制在函数内部调用 `hmac` 时的行为.
* 同时, PBKDF2 不使用 `info` 参数, 如果提供 `info`, 将被忽略.
*/
export function pbkdf2(k_hash, salt = new Uint8Array(k_hash.DIGEST_SIZE), iterations = 1000) {
const d_bit = k_hash.DIGEST_SIZE << 3;
return (k_bit, ikm) => {
ikm = joinBuffer(ikm);
/** Output Keying Material */
const okm = [];
let T;
let U;
const counter = new Counter([0, 0, 0, 1]);
for (let okm_bit = 0; okm_bit < k_bit; okm_bit += d_bit) {
T = new Uint8Array(k_hash.DIGEST_SIZE);
U = joinBuffer(salt, counter);
for (let i = 0; i < iterations; i++) {
U = k_hash(ikm, U);
T.forEach((_, j) => T[j] ^= U[j]);
}
okm.push(T);
counter.inc();
}
return joinBuffer(...okm).slice(0, k_bit >> 3);
};
}