Implement private-wrap

This commit is contained in:
2024-06-06 01:50:01 +02:00
parent 891b54034b
commit 8cb424db67
+63
View File
@@ -0,0 +1,63 @@
import {a2b64, b642a} from 'misc'
import logger from 'log'
import {SecretWrap} from './secret-wrap'
import {ecdh} from './kdf'
const log = logger('crypto:private-wrap')
const algorithm = {
name: "ECDH",
namedCurve: "P-521",
}
export class PrivateWrap {
private constructor(
private readonly box: SecretWrap,
private readonly pubkey: CryptoKey,
) {}
public static gen_keypair() : Promise<CryptoKeyPair> {
log.trace("generate keypair")
return crypto.subtle.generateKey(
algorithm,
true,
["deriveKey"],
)
}
public static async encrypt(data: CryptoKey, pubkey: CryptoKey) : Promise<PrivateWrap> {
log.trace("encrypt")
const k = await this.gen_keypair()
const kd = await ecdh(k.privateKey, pubkey)
const box = await SecretWrap.encrypt(data, kd)
return new this(box, k.publicKey)
}
public async decrypt(privkey: CryptoKey) : Promise<CryptoKey> {
log.trace("decrypt")
const kd = await ecdh(privkey, this.pubkey)
return this.box.decrypt(kd)
}
public async toString(): Promise<string> {
log.trace("toString")
const pubkey_spki = await crypto.subtle.exportKey("spki", this.pubkey)
const pubkey = a2b64(new Uint8Array(pubkey_spki))
const box = this.box.toString()
return `${pubkey}.${box}`
}
public static async fromString(data: string): Promise<PrivateWrap> {
log.trace("fromString")
const parts = data.split(".", 2)
const pubkey_str = b642a(parts[0]).expect("Failed to decode pubkey")
const pubkey = await crypto.subtle.importKey(
"spki",
pubkey_str,
algorithm,
true,
[],
)
const box = SecretWrap.fromString(parts[1])
return new PrivateWrap(box, pubkey)
}
}