Implement pwd box
ci/woodpecker/push/test Pipeline failed

This commit is contained in:
2024-05-14 15:58:35 +02:00
parent 925517ac2c
commit f30516bd2c
2 changed files with 106 additions and 7 deletions
+54 -7
View File
@@ -1,17 +1,64 @@
import type {Result} from 'result'
import {Result} from 'result'
import * as misc from 'misc'
import {SecretBox} from './symmetric'
export class PwdBox<T> {
public static encrypt<T>(pwd: string, data: Uint8Array) : PwdBox<T> {
throw "todo"
private readonly secret_box: SecretBox<T>
private readonly salt: Uint8Array
private constructor(secret_box: SecretBox<T>, salt: Uint8Array) {
this.secret_box = secret_box
this.salt = salt
}
public decrypt(pwd: string) : Result<Uint8Array> {
throw "todo"
public static async encrypt<T>(pwd: string, data: Uint8Array): Promise<PwdBox<T>> {
const salt = crypto.getRandomValues(new Uint8Array(18))
const key = await PwdBox.gen_key(pwd, salt)
const box = (await SecretBox.encrypt<T>(key, data)).unwrap() // I just created the key, I control it
return new PwdBox(box, salt)
}
public async decrypt(pwd: string): Promise<Result<Uint8Array>> {
const key = await PwdBox.gen_key(pwd, this.salt)
return this.secret_box.decrypt(key)
}
private static async gen_key(pwd: string, salt: Uint8Array) : Promise<CryptoKey> {
const keyMaterial = await window.crypto.subtle.importKey(
"raw",
new TextEncoder().encode(pwd),
"PBKDF2",
false,
["deriveBits", "deriveKey"],
)
return crypto.subtle.deriveKey(
{
name: "PBKDF2",
iterations: 250_000,
hash: "SHA-512",
salt,
},
keyMaterial,
{name: "AES-GCM", length: 256},
false,
["encrypt", "decrypt"],
)
}
public toString() : string {
throw "todo"
const salt = misc.a2b64(this.salt)
const box = this.secret_box.toString()
return `${salt}${box}`
}
public static fromString<T>(data: string) : Result<PwdBox<T>> {
throw "todo"
const salt = misc.b642a(data.slice(0, 24))
if (salt.error()) return Result.error([])
const box = SecretBox.fromString<T>(data.slice(24))
if (box.error()) return Result.error([])
return Result.ok(new PwdBox(box.unwrap(), salt.unwrap()))
}
}