| 2 | const secret = require('../config').secret; |
| 3 | |
| 4 | function Cryptr(secret) { |
| 5 | const algorithm = 'aes-256-gcm'; |
| 6 | const ivLength = 16; |
| 7 | const saltLength = 64; |
| 8 | const tagLength = 16; |
| 9 | const tagPosition = saltLength + ivLength; |
| 10 | const encryptedPosition = tagPosition + tagLength; |
| 11 | |
| 12 | if (!secret || typeof secret !== 'string') { |
| 13 | throw new Error('Cryptr: secret must be a non-0-length string'); |
| 14 | } |
| 15 | |
| 16 | function getKey(salt) { |
| 17 | return crypto.pbkdf2Sync(secret, salt, 100000, 32, 'sha512'); |
| 18 | } |
| 19 | |
| 20 | this.encrypt = function encrypt(value) { |
| 21 | if (value == null) { |
| 22 | throw new Error('Cryptr: value must not be null or undefined'); |
| 23 | } |
| 24 | |
| 25 | const iv = crypto.randomBytes(ivLength); |
| 26 | const salt = crypto.randomBytes(saltLength); |
| 27 | const key = getKey(salt); |
| 28 | const cipher = crypto.createCipheriv(algorithm, key, iv); |
| 29 | const encrypted = Buffer.concat([cipher.update(String(value), 'utf8'), cipher.final()]); |
| 30 | const tag = cipher.getAuthTag(); |
| 31 | |
| 32 | return Buffer.concat([salt, iv, tag, encrypted]).toString('hex'); |
| 33 | }; |
| 34 | |
| 35 | this.decrypt = function decrypt(value) { |
| 36 | if (value == null) { |
| 37 | throw new Error('Crypt: value must not be null or undefined'); |
| 38 | } |
| 39 | |
| 40 | const stringValue = Buffer.from(String(value), 'hex'); |
| 41 | const salt = stringValue.slice(0, saltLength); |
| 42 | const iv = stringValue.slice(saltLength, tagPosition); |
| 43 | const tag = stringValue.slice(tagPosition, encryptedPosition); |
| 44 | const encrypted = stringValue.slice(encryptedPosition); |
| 45 | const key = getKey(salt); |
| 46 | const decipher = crypto.createDecipheriv(algorithm, key, iv); |
| 47 | |
| 48 | decipher.setAuthTag(tag); |
| 49 | |
| 50 | return decipher.update(encrypted) + decipher.final('utf8'); |
| 51 | }; |
| 52 | } |
| 53 | |
| 54 | module.exports = { |
| 55 | encText(text) { |