This commit is contained in:
Pascal Perrenoud
2024-07-27 13:35:17 +02:00
parent 5cc375bd5a
commit 81ec3e9ed0
7 changed files with 364 additions and 390 deletions
+34 -47
View File
@@ -7,57 +7,44 @@ import {ecdh} from './kdf'
const log = logger('crypto:private-wrap')
const algorithm = {
name: "ECDH",
namedCurve: "P-521",
name: 'ECDH',
namedCurve: 'P-521'
}
export class PrivateWrap {
private constructor(
private readonly box: SecretWrap,
private readonly pubkey: CryptoKey,
) {}
private constructor(private readonly box: SecretWrap, private readonly pubkey: CryptoKey) {}
public static gen_keypair(extractable : boolean = true) : Promise<CryptoKeyPair> {
log.trace("generate keypair")
return crypto.subtle.generateKey(
algorithm,
extractable,
["deriveKey"],
)
}
public static gen_keypair(extractable: boolean = true): Promise<CryptoKeyPair> {
log.trace('generate keypair')
return crypto.subtle.generateKey(algorithm, extractable, ['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 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)
}
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)
}
}