Implement secret-box
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import logger from 'log'
|
||||
import {a2b64, b642a} from 'misc'
|
||||
|
||||
const log = logger('crypto:secret-box')
|
||||
|
||||
export class SecretBox {
|
||||
private constructor(
|
||||
private readonly iv: Uint8Array,
|
||||
private readonly cipher: Uint8Array,
|
||||
) {}
|
||||
|
||||
public static gen_key() : Promise<CryptoKey> {
|
||||
log.trace("generate key")
|
||||
return crypto.subtle.generateKey(
|
||||
{
|
||||
name: "AES-GCM",
|
||||
length: 256,
|
||||
},
|
||||
true,
|
||||
["encrypt", "decrypt"],
|
||||
)
|
||||
}
|
||||
|
||||
public static async encrypt(data: Uint8Array, key: CryptoKey) : Promise<SecretBox> {
|
||||
log.trace("encrypt")
|
||||
const iv = crypto.getRandomValues(new Uint8Array(11))
|
||||
const cipher = await crypto.subtle.encrypt(
|
||||
{
|
||||
name: "AES-GCM",
|
||||
iv,
|
||||
},
|
||||
key,
|
||||
data
|
||||
)
|
||||
return new SecretBox(iv, new Uint8Array(cipher))
|
||||
}
|
||||
public async decrypt(key: CryptoKey) : Promise<Uint8Array> {
|
||||
log.trace("decrypt")
|
||||
const buffer = await crypto.subtle.decrypt(
|
||||
{
|
||||
name: "AES-GCM",
|
||||
iv: this.iv
|
||||
},
|
||||
key,
|
||||
this.cipher
|
||||
)
|
||||
return new Uint8Array(buffer)
|
||||
}
|
||||
|
||||
public toString() : string {
|
||||
log.trace("toString")
|
||||
const iv = a2b64(this.iv)
|
||||
const cipher = a2b64(this.iv)
|
||||
return `${iv}.${cipher}`
|
||||
}
|
||||
public static fromString(data: string) : SecretBox {
|
||||
log.trace("fromString")
|
||||
const parts = data.split(".", 2)
|
||||
const iv = b642a(parts[0]).expect("Failed decode IV")
|
||||
const cipher = b642a(parts[1]).expect("Failed to decode cipher")
|
||||
return new SecretBox(iv, cipher)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user