Rework API

This commit is contained in:
2024-09-09 16:10:08 +02:00
parent 7aee1ee379
commit 57ca4bf78d
12 changed files with 355 additions and 273 deletions
+51
View File
@@ -0,0 +1,51 @@
import logger from 'log'
import {hkdf, pbkdf, Usage} from './kdf'
import SecretBox from './secret-box'
import {a2b64, b642a} from 'misc'
const log = logger('crypto:pwd-box')
export default class PwdBox {
private constructor(
private readonly box: SecretBox,
private readonly salt: Uint8Array
) {}
private static async derive(pwd: string, salt: Uint8Array): Promise<CryptoKey> {
const k = await pbkdf(salt, pwd)
return (await hkdf(k, Usage.box)) as CryptoKey
}
public static async encrypt(data: Uint8Array, pwd: string): Promise<PwdBox> {
log.trace('encrypt')
const salt = crypto.getRandomValues(new Uint8Array(16))
const k = await PwdBox.derive(pwd, salt)
const box = await SecretBox.encrypt(data, k)
return new PwdBox(box, salt)
}
public async decrypt(pwd: string): Promise<Uint8Array | null> {
log.trace('decrypt')
const k = await PwdBox.derive(pwd, this.salt)
return this.box.decrypt(k)
}
public toString(): string {
log.trace('toString')
const salt = a2b64(this.salt)
const box = this.box.toString()
return `${salt}.${box}`
}
public static fromString(data: string): PwdBox | null {
log.trace('fromString')
const parts = data.split('.')
if (parts.length < 2) return null
const salt = b642a(parts[0])
if (salt === null) return null
const box = SecretBox.fromString(parts.slice(1).join("."))
if (box === null) return null
return new PwdBox(box, salt)
}
}