pwd-wrap : Implement

This commit is contained in:
2024-09-04 21:10:10 +02:00
parent ca7cde47f8
commit 5d3d23ca4a
2 changed files with 50 additions and 0 deletions
+1
View File
@@ -6,3 +6,4 @@ export * as JWT from "./src/jwt"
export {SecretBox} from './src/secret-box'
export {PrivateWrap} from './src/private-wrap'
export {SecretWrap} from './src/secret-wrap'
export {PwdWrap} from './src/pwd-wrap'
+49
View File
@@ -0,0 +1,49 @@
import {hkdf, pbkdf, Usage} from './kdf'
import {SecretWrap} from './secret-wrap'
import logger from 'log'
import {a2b64, b642a} from "misc";
const log = logger('crypto:pwd-wrap')
export class PwdWrap {
private constructor(private readonly box: SecretWrap, 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.wrap) as CryptoKey
}
public static async encrypt(data: CryptoKey, pwd: string, salt?: Uint8Array) : Promise<PwdWrap> {
log.trace('encrypt')
salt = salt ?? crypto.getRandomValues(new Uint8Array(16))
const k = await PwdWrap.derive(pwd, salt)
const box = await SecretWrap.encrypt(data, k)
return new PwdWrap(box, salt)
}
public async decrypt(pwd: string) : Promise<CryptoKey> {
log.trace('decrypt')
const k = await PwdWrap.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 fromString(data: string): PwdWrap | null {
log.trace('fromString')
const parts = data.split('.', 2)
if (parts.length !== 2) return null
const salt = b642a(parts[0])
if (salt.is_err()) return null
const box = SecretWrap.fromString(parts[1])
if (box === null) return null
return new PwdWrap(box, salt.unwrap())
}
}