-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
91 lines (80 loc) · 3.36 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
const crypto = require('crypto')
const bip39 = require('bip39')
const fs = require('fs')
const readline = require('readline');
const qrcode = require('qrcode-terminal');
const argon2 = require('argon2-browser');
const algorithm = 'aes-256-gcm'
const createHashedPassword = async (password, iv) => {
const numIterations = 1000;
console.log(`\nHashing password with ${numIterations} iterations\nThis will take a few seconds...`)
const { hash } = await argon2.hash({
pass: password,
time: numIterations,
mem: 4096,
salt: iv.toString('hex'),
hashLen: 32
});
return hash;
}
const encrypt = async (secretPhrase, password) => {
const iv = crypto.randomBytes(16)
const hash = await createHashedPassword(password, iv)
const cipher = crypto.createCipheriv(algorithm, hash, iv)
const encrypted = Buffer.concat([cipher.update(secretPhrase), cipher.final()])
const encryptedSecretPhrase = {
iv: iv.toString('hex'),
content: encrypted.toString('hex'),
tag: cipher.getAuthTag()
}
return encryptedSecretPhrase;
}
const decrypt = (encryptedJSON, key) => {
const decipher = crypto.createDecipheriv(algorithm, key, Buffer.from(encryptedJSON.iv, 'hex')).setAuthTag(Buffer.from(encryptedJSON.tag, 'hex'))
const decrpyted = Buffer.concat([decipher.update(Buffer.from(encryptedJSON.content, 'hex')), decipher.final()])
return decrpyted.toString()
}
const askQuestion = (query) => {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
return new Promise(resolve => rl.question(query, ans => {
rl.close();
resolve(ans);
}))
}
const createAndEncrypt = async () => {
const password = await askQuestion('Enter password to encrypt your secret pharse: ')
console.log('Your secret key is: ', password)
const secretPhrase = bip39.generateMnemonic();
console.log('Your secret phrase is: ', secretPhrase)
const encryptedSecretPhrase = await encrypt(secretPhrase, password)
fs.writeFileSync('SecretPhrase.json', JSON.stringify(encryptedSecretPhrase))
console.log("Your secret phrase has been encrypted and saved to SecretPhrase.json")
console.log("Now you can safely backup SecretPhrase.json to Google Drive, WhatsApp, iCloud, etc.")
console.error("Note: You MUST use this tool to decrypt your secret phrase in the future.")
console.log("\nScan this QR Code with your wallet to import your account.")
qrcode.generate(secretPhrase, {small: true});
}
const decryptSecretPhrase = async () => {
const password = await askQuestion('Enter password to decrypt your secret pharse: ')
const encryptedSecretPhrase = JSON.parse(fs.readFileSync('SecretPhrase.json'))
const hash = await createHashedPassword(password, encryptedSecretPhrase.iv)
const decryptedSecretPhrase = decrypt(encryptedSecretPhrase, hash)
console.log('Your decrypted secret phrase is: ', decryptedSecretPhrase)
console.log("\nScan this QR Code with your wallet to import your account.")
qrcode.generate(decryptedSecretPhrase, {small: true});
}
const main = async () => {
const mode = await askQuestion('Encrypt or Decrypt? Enter e or d: ')
if (mode === 'e') {
return createAndEncrypt()
}
if (mode === 'd') {
return decryptSecretPhrase()
}
console.log("You did not enter e or d")
process.exit(1)
}
main()