-
-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathEncrypter.imba
More file actions
103 lines (72 loc) · 3.15 KB
/
Copy pathEncrypter.imba
File metadata and controls
103 lines (72 loc) · 3.15 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
import isString from '../Support/Helpers/isString'
import config from '../Support/Helpers/config'
import crypto from 'crypto'
import DecryptException from './Exceptions/DecryptException'
import EncryptException from './Exceptions/EncryptException'
import InvalidAppKeyException from './Exceptions/InvalidAppKeyException'
import InvalidEncryptionKeyTypeException from './Exceptions/InvalidEncryptionKeyTypeException'
import isEmpty from '../Support/Helpers/isEmpty'
import isObject from '../Support/Helpers/isObject'
const settings = {
algorithm: null
appKey: null
}
def configureEncrypter
try
if isEmpty(settings.algorithm)
settings.algorithm = config('app.cipher', 'AES-256-CBC')
if isEmpty(settings.appKey)
settings.appKey = config('app.key', new String)
catch e
configureEncrypter!
export default class Encrypter
static def configure config\object
if !isObject(config) then throw TypeError 'Expected an object.'
if !isEmpty(config.algorithm) && isEmpty(settings.algorithm)
settings.algorithm = config.algorithm
if !isEmpty(config.appKey) && isEmpty(settings.appKey)
settings.appKey = config.appKey
Encrypter
static def appKey type\string
configureEncrypter!
if !isEmpty(type) && ['key', 'iv'].includes(type.toLowerCase()) == false
throw new InvalidEncryptionKeyTypeException 'Encryption key type is not valid.'
let key\string = isString(settings.appKey) ? settings.appKey : new String
if key.startsWith('base64:')
key = Buffer.from(key.split('base64:')[1], 'base64').toString('utf-8')
if isEmpty(type) then return key
if type.toLowerCase() == 'key' then return key.split(':')[0]
if type.toLowerCase() == 'iv' then return key.split(':')[1]
static def key
self.appKey 'key'
static def iv
self.appKey 'iv'
static def encrypt value\any
if isEmpty(settings.algorithm) || isEmpty(settings.appKey)
throw new InvalidAppKeyException 'Application key is not valid.'
try
const cipher = crypto.createCipheriv(settings.algorithm, self.key!, self.iv!)
Buffer.concat([cipher.update(JSON.stringify(value)), cipher.final()]).toString('hex')
catch
throw new EncryptException 'Encryption failed.'
static def decrypt hash\string
if isEmpty(settings.algorithm) || isEmpty(settings.appKey)
throw new InvalidAppKeyException 'Application key is not valid.'
try
const decipher = crypto.createDecipheriv(settings.algorithm, self.key!, self.iv!);
const decrypted = Buffer.concat([decipher.update(Buffer.from(hash, 'hex')), decipher.final()]).toString!
JSON.parse(decrypted)
catch
throw new DecryptException 'Invalid data.'
static def hashEquals knownString\string, userString\string
if !isString(knownString)
throw TypeError 'Expected "knownString" to be a string.'
if !isString(userString)
throw TypeError 'Expected "userString" to be a string.'
const randomBytes = crypto.randomBytes(32)
const knownHash = crypto.createHmac('sha256', randomBytes).update(knownString).digest('hex')
const userHash = crypto.createHmac('sha256', randomBytes).update(userString).digest('hex')
let results = 0
for i in [0 .. knownHash.length]
results != (knownHash.charCodeAt(i) ^ userHash.charCodeAt(i))
results == 0