feat: add libsodium for crypto

This commit is contained in:
thecodrr
2020-04-13 16:06:54 +05:00
parent 8912c35509
commit 28cf586c26
4 changed files with 117 additions and 2 deletions

View File

@@ -10,6 +10,7 @@
"framer-motion": "^1.9.1",
"git": "^0.1.5",
"immer": "^5.3.6",
"libsodium-wrappers": "0.7.6",
"localforage": "^1.7.3",
"localforage-getitems": "https://github.com/thecodrr/localForage-getItems.git",
"notes-core": "npm:@streetwriters/notesnook-core@latest",

View File

@@ -0,0 +1,109 @@
class Crypto {
isReady = false;
constructor() {
this.sodium = undefined;
}
async _initialize() {
if (this.isReady) return;
const _sodium = require("libsodium-wrappers");
await _sodium.ready;
this.sodium = _sodium;
this.isReady = true;
}
deriveKey = async (password, salt, exportKey = false) => {
await this._initialize();
if (!salt)
salt = this.sodium.randombytes_buf(this.sodium.crypto_pwhash_SALTBYTES);
else {
salt = this.sodium.from_base64(salt);
}
const key = this.sodium.crypto_pwhash(
this.sodium.crypto_aead_xchacha20poly1305_ietf_KEYBYTES,
password,
salt,
3, // operations limit
1024 * 1024 * 8, // memory limit (8MB)
this.sodium.crypto_pwhash_ALG_ARGON2I13,
exportKey ? "hex" : "uint8array"
);
const saltHex = this.sodium.to_base64(salt);
this.sodium.memzero(salt);
if (exportKey) {
return key;
}
return { key, salt: saltHex };
};
_getKey = async (passwordOrKey) => {
let key, salt;
if (passwordOrKey.password) {
const result = await this.deriveKey(passwordOrKey.password);
key = result.key;
salt = result.salt;
} else if (passwordOrKey.key && passwordOrKey.salt) {
salt = passwordOrKey.salt;
key = this.sodium.from_hex(passwordOrKey.key);
}
return { key, salt };
};
/**
*
* @param {{password: string}|{key:string, salt: string}} passwordOrKey - password or derived key
* @param {string|Object} data - the plaintext data
*/
encrypt = async (passwordOrKey, data) => {
await this._initialize();
if (typeof data === "object") data = JSON.stringify(data);
const { key, salt } = await this._getKey(passwordOrKey);
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_base64(nonce);
this.sodium.memzero(nonce);
this.sodium.memzero(key);
return {
cipher,
iv,
salt,
};
};
/**
*
* @param {{password: string}|{key:string, salt: string}} passwordOrKey - password or derived key
* @param {{salt: string, iv: string, cipher: string}} cipher - the cipher data
*/
decrypt = async (passwordOrKey, { iv, cipher }) => {
await this._initialize();
const { key } = await this._getKey(passwordOrKey);
console.log(key, iv, cipher, passwordOrKey);
const plainText = this.sodium.crypto_aead_xchacha20poly1305_ietf_decrypt(
undefined,
this.sodium.from_base64(cipher),
undefined,
this.sodium.from_base64(iv),
key,
"text"
);
this.sodium.memzero(key);
return plainText;
};
}
export default Crypto;

View File

@@ -1,7 +1,9 @@
import localforage from "localforage";
import { extendPrototype } from "localforage-getitems";
import sort from "fast-sort";
import Crypto from "./crypto";
const crypto = new Crypto();
extendPrototype(localforage);
localforage.config({
@@ -36,4 +38,7 @@ export default {
write,
remove,
clear,
deriveKey: crypto.deriveKey,
encrypt: crypto.encrypt,
decrypt: crypto.decrypt,
};

View File

@@ -6268,7 +6268,7 @@ levn@^0.3.0, levn@~0.3.0:
prelude-ls "~1.1.2"
type-check "~0.3.2"
libsodium-wrappers@^0.7.6:
libsodium-wrappers@0.7.6, libsodium-wrappers@^0.7.6:
version "0.7.6"
resolved "https://registry.yarnpkg.com/libsodium-wrappers/-/libsodium-wrappers-0.7.6.tgz#baed4c16d4bf9610104875ad8a8e164d259d48fb"
integrity sha512-OUO2CWW5bHdLr6hkKLHIKI4raEkZrf3QHkhXsJ1yCh6MZ3JDA7jFD3kCATNquuGSG6MjjPHQIQms0y0gBDzjQg==
@@ -6910,7 +6910,7 @@ normalize-url@^3.0.0, normalize-url@^3.0.1:
"notes-core@git+ssh://git@github.com:thecodrr/notes-core.git":
version "1.2.0"
resolved "git+ssh://git@github.com:thecodrr/notes-core.git#47dcb328be59c040c7ea50a6e1f26a2572ee1270"
resolved "git+ssh://git@github.com:thecodrr/notes-core.git#d0e226b0ba97a44f7098955ee6d982904a51be9d"
dependencies:
fast-sort "^2.0.1"
fuzzysearch "^1.0.3"