lbry-desktop/electron/sync/sync.js

87 lines
2.7 KiB
JavaScript

import crypto from 'crypto';
export function generateSalt(email, seed) {
const hashInput = (email + ':' + seed).toString('utf8');
const hash = crypto.createHash('sha256');
hash.update(hashInput);
const hash_output = hash.digest('hex').toString('utf8');
return hash_output;
}
export function generateSaltSeed() {
return crypto.randomBytes(32).toString('hex');
}
export function createHmac(serverWalletState, hmacKey) {
return crypto.randomBytes(32).toString('hex');
}
export function checkHmac(serverWalletState, hmacKey, hmac) {
return crypto.randomBytes(32).toString('hex');
}
export function deriveSecrets(rootPassword, email, saltSeed, callback) {
const encodedPassword = Buffer.from(rootPassword.normalize('NFKC'));
const encodedEmail = Buffer.from(email);
const SCRYPT_N = 1 << 20;
const SCRYPT_R = 8;
const SCRYPT_P = 1;
const KEY_LENGTH = 32;
const NUM_KEYS = 3;
const MAXMEM_MULTIPLIER = 256;
const DEFAULT_MAXMEM = MAXMEM_MULTIPLIER * SCRYPT_N * SCRYPT_R;
function getKeyParts(key) {
const providerKey = key.slice(0, KEY_LENGTH).toString('base64');
const hmacKey = key.slice(KEY_LENGTH, KEY_LENGTH * 2).toString('base64');
const dataKey = key.slice(KEY_LENGTH * 2).toString('base64');
return { providerKey, hmacKey, dataKey }; // Buffer aa bb cc 6c
}
const salt = generateSalt(encodedEmail, saltSeed);
const scryptCallback = (err, key) => {
if (err) {
// handle error
}
callback(err, getKeyParts(key));
};
crypto.scrypt(encodedPassword, salt, KEY_LENGTH * NUM_KEYS, { N: SCRYPT_N, r: SCRYPT_R, p: SCRYPT_P, maxmem: DEFAULT_MAXMEM }, scryptCallback);
}
export function walletHmac(inputString, hmacKey) {
const res = crypto.createHmac('sha256', hmacKey)
.update(inputString.toString('utf8'))
.digest('hex');
console.log('hmac res', res)
return res;
}
export function aesEncrypt(text, key) {
try {
const iv = crypto.randomBytes(16);
let cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(key), iv);
let encrypted = cipher.update(text);
encrypted = Buffer.concat([encrypted, cipher.final()]);
return { iv: iv.toString('hex'), encryptedData: encrypted.toString('hex') };
} catch (e) {
return { error: `Wallet decrypt failed error: ${e.message}` };
}
}
export function aesDecrypt(cipher, key) {
try {
let iv = Buffer.from(cipher.iv, 'hex');
let encryptedText = Buffer.from(cipher.encryptedData, 'hex');
let decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(key), iv);
let decrypted = decipher.update(encryptedText);
decrypted = Buffer.concat([decrypted, decipher.final()]);
// handle errors here
return { result: decrypted.toString() };
} catch (e) {
return { error: `Wallet decrypt failed error: ${e.message}`};
}
}