pwd-wrap : Implement
This commit is contained in:
@@ -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'
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user