This commit is contained in:
Pascal Perrenoud
2024-07-27 13:35:17 +02:00
parent 5cc375bd5a
commit 81ec3e9ed0
7 changed files with 364 additions and 390 deletions
+70 -80
View File
@@ -2,89 +2,79 @@ import logger from 'log'
const log = logger('crypto:kdf')
export enum Usage {
sign,
wrap,
sign,
wrap
}
export async function hkdf(key: Uint8Array, usage: Usage) : Promise<CryptoKey | Uint8Array> {
log.trace("HKDF")
log.trace(`usage : ${usage === Usage.sign ? 'sign' : 'wrap'}`)
export async function hkdf(key: Uint8Array, usage: Usage): Promise<CryptoKey | Uint8Array> {
log.trace('HKDF')
log.trace(`usage : ${usage === Usage.sign ? 'sign' : 'wrap'}`)
const material = await crypto.subtle.importKey(
"raw",
key,
"HKDF",
false,
["deriveKey", "deriveBits"],
)
const material = await crypto.subtle.importKey('raw', key, 'HKDF', false, ['deriveKey', 'deriveBits'])
if (usage === Usage.wrap) {
return crypto.subtle.deriveKey(
{
name: "HKDF",
hash: "SHA-512",
salt: new Uint8Array(32),
info: new TextEncoder().encode("wrap"),
},
material,
{name: "AES-GCM", length: 256},
false,
["wrapKey", "unwrapKey"],
)
} else if (usage === Usage.sign) {
const buffer = await crypto.subtle.deriveBits(
{
name: "HKDF",
hash: "SHA-512",
salt: new Uint8Array(32),
info: new TextEncoder().encode("sign"),
},
material,
512
)
return new Uint8Array(buffer)
} else {
log.warn(`Called HKDF with unknown enum value : ${usage}`)
throw "I don't even know what to say."
}
}
export async function pbkdf(salt: Uint8Array, password: string) : Promise<Uint8Array> {
log.trace("PBKDF")
const material = await crypto.subtle.importKey(
"raw",
new TextEncoder().encode(password),
"PBKDF2",
false,
["deriveBits"],
)
const buffer = await crypto.subtle.deriveBits(
{
name: "PBKDF2",
salt,
iterations: 250_000,
hash: "SHA-512",
},
material,
256,
)
return new Uint8Array(buffer)
}
export function ecdh(privkey: CryptoKey, pubkey: CryptoKey) : Promise<CryptoKey> {
log.trace("ECDH")
if (usage === Usage.wrap) {
return crypto.subtle.deriveKey(
{
name: "ECDH",
public: pubkey,
},
privkey,
{
name: "AES-GCM",
length: 256,
},
false,
["wrapKey", "unwrapKey"],
{
name: 'HKDF',
hash: 'SHA-512',
salt: new Uint8Array(32),
info: new TextEncoder().encode('wrap')
},
material,
{name: 'AES-GCM', length: 256},
false,
['wrapKey', 'unwrapKey']
)
} else if (usage === Usage.sign) {
const buffer = await crypto.subtle.deriveBits(
{
name: 'HKDF',
hash: 'SHA-512',
salt: new Uint8Array(32),
info: new TextEncoder().encode('sign')
},
material,
512
)
return new Uint8Array(buffer)
} else {
log.warn(`Called HKDF with unknown enum value : ${usage}`)
throw "I don't even know what to say."
}
}
export async function pbkdf(salt: Uint8Array, password: string): Promise<Uint8Array> {
log.trace('PBKDF')
const material = await crypto.subtle.importKey('raw', new TextEncoder().encode(password), 'PBKDF2', false, [
'deriveBits'
])
const buffer = await crypto.subtle.deriveBits(
{
name: 'PBKDF2',
salt,
iterations: 250_000,
hash: 'SHA-512'
},
material,
256
)
return new Uint8Array(buffer)
}
export function ecdh(privkey: CryptoKey, pubkey: CryptoKey): Promise<CryptoKey> {
log.trace('ECDH')
return crypto.subtle.deriveKey(
{
name: 'ECDH',
public: pubkey
},
privkey,
{
name: 'AES-GCM',
length: 256
},
false,
['wrapKey', 'unwrapKey']
)
}