mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-23 06:59:31 +01:00
88 lines
2.0 KiB
JavaScript
88 lines
2.0 KiB
JavaScript
import _sodium from "libsodium-wrappers";
|
|
|
|
export async function newSodium() {
|
|
await _sodium.ready;
|
|
return _sodium;
|
|
}
|
|
|
|
class Crypto {
|
|
constructor() {
|
|
this.isReady = false;
|
|
this.sodium = _sodium;
|
|
}
|
|
|
|
async init() {
|
|
this.sodium = await newSodium();
|
|
this.isReady = true;
|
|
}
|
|
|
|
_throwIfNotReady() {
|
|
if (!this.isReady)
|
|
throw new Error("libsodium is not ready yet. Please call init()");
|
|
}
|
|
|
|
_deriveKey(password, keyLength, salt) {
|
|
this._throwIfNotReady();
|
|
salt =
|
|
salt || this.sodium.randombytes_buf(this.sodium.crypto_pwhash_SALTBYTES);
|
|
const key = this.sodium.crypto_pwhash(
|
|
keyLength,
|
|
password,
|
|
salt,
|
|
3, // operations limit
|
|
1024 * 1024 * 4, // memory limit (4MB)
|
|
this.sodium.crypto_pwhash_ALG_ARGON2I13
|
|
);
|
|
const saltHex = this.sodium.to_hex(salt);
|
|
this.sodium.memzero(salt);
|
|
return { key, salt: saltHex };
|
|
}
|
|
|
|
encrypt({ password, data }) {
|
|
this._throwIfNotReady();
|
|
const { key, salt } = this._deriveKey(
|
|
password,
|
|
this.sodium.crypto_aead_xchacha20poly1305_ietf_KEYBYTES
|
|
);
|
|
const nonce = this.sodium.randombytes_buf(
|
|
this.sodium.crypto_aead_xchacha20poly1305_ietf_NPUBBYTES
|
|
);
|
|
const cipher = this.sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(
|
|
data,
|
|
undefined,
|
|
undefined,
|
|
nonce,
|
|
key,
|
|
"base64"
|
|
);
|
|
const iv = this.sodium.to_hex(nonce);
|
|
this.sodium.memzero(nonce);
|
|
this.sodium.memzero(key);
|
|
return {
|
|
cipher,
|
|
iv,
|
|
salt,
|
|
};
|
|
}
|
|
|
|
decrypt({ password, data: { salt, iv, cipher } }) {
|
|
this._throwIfNotReady();
|
|
const { key } = this._deriveKey(
|
|
password,
|
|
this.sodium.crypto_aead_xchacha20poly1305_ietf_KEYBYTES,
|
|
this.sodium.from_hex(salt)
|
|
);
|
|
const plainText = this.sodium.crypto_aead_xchacha20poly1305_ietf_decrypt(
|
|
undefined,
|
|
this.sodium.from_base64(cipher),
|
|
undefined,
|
|
this.sodium.from_hex(iv),
|
|
key,
|
|
"text"
|
|
);
|
|
this.sodium.memzero(key);
|
|
return plainText;
|
|
}
|
|
}
|
|
export default Crypto;
|