-
-
Notifications
You must be signed in to change notification settings - Fork 48
Expand file tree
/
Copy pathindex.js
More file actions
153 lines (111 loc) · 4.5 KB
/
index.js
File metadata and controls
153 lines (111 loc) · 4.5 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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
const crypto = require('crypto');
const util = require('util');
const algorithm = 'aes-256-gcm';
const ivLength = 16;
const tagLength = 16;
const defaultEncoding = 'hex';
const defaultSaltLength = 64;
const defaultPbkdf2Iterations = 100000;
function Cryptr(secret, options) {
if (!secret || typeof secret !== 'string') {
throw new Error('Cryptr: secret must be a non-0-length string');
}
let encoding = defaultEncoding;
let saltLength = defaultSaltLength;
let pbkdf2Iterations = defaultPbkdf2Iterations;
if (options) {
if (options.encoding) {
encoding = options.encoding;
}
if (options.pbkdf2Iterations) {
pbkdf2Iterations = options.pbkdf2Iterations;
}
if (options.saltLength) {
saltLength = options.saltLength;
}
}
const tagPosition = saltLength + ivLength;
const encryptedPosition = tagPosition + tagLength;
function getKey(salt) {
return crypto.pbkdf2Sync(secret, salt, pbkdf2Iterations, 32, 'sha512');
}
this.encrypt = function encrypt(value) {
if (value == null) {
throw new Error('value must not be null or undefined');
}
const iv = crypto.randomBytes(ivLength);
const salt = crypto.randomBytes(saltLength);
const key = getKey(salt);
const cipher = crypto.createCipheriv(algorithm, key, iv);
const encrypted = Buffer.concat([cipher.update(String(value), 'utf8'), cipher.final()]);
const tag = cipher.getAuthTag();
return Buffer.concat([salt, iv, tag, encrypted]).toString(encoding);
};
this.decrypt = function decrypt(value) {
if (value == null) {
throw new Error('value must not be null or undefined');
}
const stringValue = Buffer.from(String(value), encoding);
const salt = stringValue.subarray(0, saltLength);
const iv = stringValue.subarray(saltLength, tagPosition);
const tag = stringValue.subarray(tagPosition, encryptedPosition);
const encrypted = stringValue.subarray(encryptedPosition);
const key = getKey(salt);
const decipher = crypto.createDecipheriv(algorithm, key, iv);
decipher.setAuthTag(tag);
return decipher.update(encrypted) + decipher.final('utf8');
};
}
function CryptrAsync(secret, options) {
if (!secret || typeof secret !== 'string') {
throw new Error('Cryptr: secret must be a non-0-length string');
}
let encoding = defaultEncoding;
let saltLength = defaultSaltLength;
let pbkdf2Iterations = defaultPbkdf2Iterations;
if (options) {
if (options.encoding) {
encoding = options.encoding;
}
if (options.pbkdf2Iterations) {
pbkdf2Iterations = options.pbkdf2Iterations;
}
if (options.saltLength) {
saltLength = options.saltLength;
}
}
const tagPosition = saltLength + ivLength;
const encryptedPosition = tagPosition + tagLength;
async function getKey(salt) {
const pbkdf2 = util.promisify(crypto.pbkdf2);
return await pbkdf2(secret, salt, pbkdf2Iterations, 32, 'sha512');
}
this.encrypt = async function encrypt(value) {
if (value == null) {
throw new Error('value must not be null or undefined');
}
const iv = crypto.randomBytes(ivLength);
const salt = crypto.randomBytes(saltLength);
const key = await getKey(salt);
const cipher = crypto.createCipheriv(algorithm, key, iv);
const encrypted = Buffer.concat([cipher.update(String(value), 'utf8'), cipher.final()]);
const tag = cipher.getAuthTag();
return Buffer.concat([salt, iv, tag, encrypted]).toString(encoding);
};
this.decrypt = async function decrypt(value) {
if (value == null) {
throw new Error('value must not be null or undefined');
}
const stringValue = Buffer.from(String(value), encoding);
const salt = stringValue.subarray(0, saltLength);
const iv = stringValue.subarray(saltLength, tagPosition);
const tag = stringValue.subarray(tagPosition, encryptedPosition);
const encrypted = stringValue.subarray(encryptedPosition);
const key = await getKey(salt);
const decipher = crypto.createDecipheriv(algorithm, key, iv);
decipher.setAuthTag(tag);
return decipher.update(encrypted) + decipher.final('utf8');
};
}
module.exports = Cryptr;
module.exports.CryptrAsync = CryptrAsync;