Improvements to HKDF

This commit is contained in:
Liran Nuna 2019-03-02 12:57:59 -08:00
parent 9e3a2ebf90
commit e8046378af
2 changed files with 9 additions and 28 deletions

View File

@ -1,20 +1,10 @@
import * as core from "webcrypto-core";
import { HmacCryptoKey } from "../hmac/key";
import { HkdfCryptoKey } from "./key";
import { BufferSourceConverter, CryptoKey } from "webcrypto-core";
import crypto from "crypto"; import crypto from "crypto";
import * as core from "webcrypto-core";
import { BufferSourceConverter, CryptoKey } from "webcrypto-core";
import { HkdfCryptoKey } from "./key";
export class HkdfProvider extends core.HkdfProvider { export class HkdfProvider extends core.HkdfProvider {
private normalizeHash(hash: HashAlgorithmIdentifier): Algorithm {
if (typeof hash === "string") {
hash = {name: hash};
}
this.checkHashAlgorithm(hash, this.hashAlgorithms);
return hash;
}
public async onImportKey(format: KeyFormat, keyData: ArrayBuffer, algorithm: HmacImportParams, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey> { public async onImportKey(format: KeyFormat, keyData: ArrayBuffer, algorithm: HmacImportParams, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey> {
if (format.toLowerCase() !== "raw") { if (format.toLowerCase() !== "raw") {
throw new core.OperationError("Operation not supported"); throw new core.OperationError("Operation not supported");
@ -28,17 +18,8 @@ export class HkdfProvider extends core.HkdfProvider {
return key; return key;
} }
public async onExportKey(format: KeyFormat, key: HmacCryptoKey): Promise<JsonWebKey | ArrayBuffer> {
switch (format.toLowerCase()) {
case "raw":
return new Uint8Array(key.data).buffer;
default:
throw new core.OperationError("format: Must be 'raw'");
}
}
public async onDeriveBits(params: HkdfParams, baseKey: HkdfCryptoKey, length: number): Promise<ArrayBuffer> { public async onDeriveBits(params: HkdfParams, baseKey: HkdfCryptoKey, length: number): Promise<ArrayBuffer> {
const hash = this.normalizeHash(params.hash).name.replace("-", ""); const hash = (params.hash as Algorithm).name.replace("-", "");
const hashLength = crypto.createHash(hash).digest().length; const hashLength = crypto.createHash(hash).digest().length;
const byteLength = length / 8; const byteLength = length / 8;
@ -48,13 +29,13 @@ export class HkdfProvider extends core.HkdfProvider {
.update(BufferSourceConverter.toUint8Array(baseKey.data)) .update(BufferSourceConverter.toUint8Array(baseKey.data))
.digest(); .digest();
let blocks = [Buffer.alloc(0)]; const blocks = [Buffer.alloc(0)];
const blockCount = Math.ceil(byteLength / hashLength) + 1; // Includes empty buffer const blockCount = Math.ceil(byteLength / hashLength) + 1; // Includes empty buffer
for (let i = 1; i < blockCount; ++i) { for (let i = 1; i < blockCount; ++i) {
blocks.push( blocks.push(
crypto.createHmac(hash, PRK) crypto.createHmac(hash, PRK)
.update(Buffer.concat([blocks[i - 1], info, Buffer.from([i])])) .update(Buffer.concat([blocks[i - 1], info, Buffer.from([i])]))
.digest() .digest(),
); );
} }

View File

@ -3,8 +3,8 @@ import {
AesCbcProvider, AesCtrProvider, AesGcmProvider, AesKwProvider, AesCbcProvider, AesCtrProvider, AesGcmProvider, AesKwProvider,
DesCbcProvider, DesEde3CbcProvider, DesCbcProvider, DesEde3CbcProvider,
EcdhProvider, EcdsaProvider, EcdhProvider, EcdsaProvider,
HmacProvider, HkdfProvider, HmacProvider,
Pbkdf2Provider, HkdfProvider, Pbkdf2Provider,
RsaOaepProvider, RsaPssProvider, RsaSsaProvider, RsaOaepProvider, RsaPssProvider, RsaSsaProvider,
Sha1Provider, Sha256Provider, Sha384Provider, Sha512Provider, Sha1Provider, Sha256Provider, Sha384Provider, Sha512Provider,
} from "./mechs"; } from "./mechs";