-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathkeyEncryption.js
More file actions
136 lines (108 loc) · 3.21 KB
/
keyEncryption.js
File metadata and controls
136 lines (108 loc) · 3.21 KB
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
const crypto = require('crypto');
const fs = require('fs');
const prompts = require('prompts');
const openpgp = require('openpgp');
const outputEncoding = "utf8";
const algorithm = "aes-256-ctr";
const encoding = "base64";
const hash = "sha256";
const EncryptionMethod = {
GPG: "gpg",
BUILTIN: "builtin"
}
class KeyEncryption {
constructor(configFileInfo) {
this.configFileInfo = configFileInfo;
}
async loadKey() {
if (fs.existsSync(this.configFileInfo.name)) {
return await this.readPrivateKey();
}
else {
return await this.writePrivateKey();
// throw Error(".config file for privateKey not found")
}
}
async writePrivateKey() {
const { privateKey, password } = await prompts([
{
type: "text",
name: "privateKey",
message: "private key:",
},
{
type: "password",
name: "password",
message: "password:",
},
]);
if (this.configFileInfo.encryptionMethod === EncryptionMethod.GPG) {
await this._saveToConfig(await this.encryptGpg(privateKey, password));
} else {
await this._saveToConfig(await this.encrypt(privateKey, password));
}
console.log("saved to", this.configFileInfo.name);
return privateKey
}
async _saveToConfig(encrypted) {
fs.writeFile(this.configFileInfo.name, encrypted, function (err) {
if (err) return console.log(err);
console.log('epk was written to file');
});
}
async encrypt(text, password) {
const key = crypto.createHash(hash).update(String(password)).digest();
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(algorithm, key, iv);
let result = cipher.update(text, outputEncoding, encoding);
result += cipher.final(encoding);
return `${iv.toString(encoding)}:${result}`;
}
async encryptGpg(text, password) {
const encrypted = await openpgp.encrypt({
message: await openpgp.createMessage({ text: text }), // input as Message object
format: "armored",
passwords: password,
});
return encrypted;
}
async readPrivateKey() {
const epk = fs.readFileSync(this.configFileInfo.name, {'encoding': 'utf8'});
if (this.configFileInfo.encryptionMethod === EncryptionMethod.GPG) {
return await this.decryptGpg(epk)
} else {
return await this.decrypt(epk)
}
}
async decrypt(encryptedData) {
const password = process.env.PASSWORD;
if (!password || !password.length) throw new Error("invalid password");
const key = crypto.createHash(hash).update(String(password)).digest();
const [ivText, encrypted] = encryptedData.split(":");
const iv = Buffer.from(ivText, encoding);
const decipher = crypto.createDecipheriv(algorithm, key, iv);
let result = decipher.update(encrypted, encoding, outputEncoding);
result += decipher.final(outputEncoding);
return result;
}
async decryptGpg(encryptedData) {
let password;
const input = await prompts({
type: "password",
name: "password",
message: "password",
});
password = input.password;
if (!password || !password.length) throw new Error("invalid password");
const decrypted = await openpgp.decrypt({
message: await openpgp.readMessage({armoredMessage: encryptedData}),
passwords: password,
format: 'utf8'
})
return decrypted.data.trim();
}
}
module.exports = {
EncryptionMethod,
KeyEncryption,
}