mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-16 01:24:05 -08:00
0bd4e742da
[`crypto-js` has been
discontinued](1da3dabf93
)
PS: We'll remove `crypto-js` usage from `n8n-workflow` and
`@n8n_io/license-sdk` in separate PRs.
44 lines
1.6 KiB
TypeScript
44 lines
1.6 KiB
TypeScript
import { Service } from 'typedi';
|
|
import { createHash, createCipheriv, createDecipheriv, randomBytes } from 'crypto';
|
|
import { InstanceSettings } from './InstanceSettings';
|
|
|
|
// Data encrypted by CryptoJS always starts with these bytes
|
|
const RANDOM_BYTES = Buffer.from('53616c7465645f5f', 'hex');
|
|
|
|
@Service()
|
|
export class Cipher {
|
|
constructor(private readonly instanceSettings: InstanceSettings) {}
|
|
|
|
encrypt(data: string | object) {
|
|
const salt = randomBytes(8);
|
|
const [key, iv] = this.getKeyAndIv(salt);
|
|
const cipher = createCipheriv('aes-256-cbc', key, iv);
|
|
const encrypted = cipher.update(typeof data === 'string' ? data : JSON.stringify(data));
|
|
return Buffer.concat([RANDOM_BYTES, salt, encrypted, cipher.final()]).toString('base64');
|
|
}
|
|
|
|
decrypt(data: string) {
|
|
const input = Buffer.from(data, 'base64');
|
|
if (input.length < 16) return '';
|
|
const salt = input.subarray(8, 16);
|
|
const [key, iv] = this.getKeyAndIv(salt);
|
|
const contents = input.subarray(16);
|
|
const decipher = createDecipheriv('aes-256-cbc', key, iv);
|
|
return Buffer.concat([decipher.update(contents), decipher.final()]).toString('utf-8');
|
|
}
|
|
|
|
private getKeyAndIv(salt: Buffer): [Buffer, Buffer] {
|
|
const { encryptionKey } = this.instanceSettings;
|
|
const password = Buffer.concat([Buffer.from(encryptionKey, 'binary'), salt]);
|
|
const hash1 = createHash('md5').update(password).digest();
|
|
const hash2 = createHash('md5')
|
|
.update(Buffer.concat([hash1, password]))
|
|
.digest();
|
|
const iv = createHash('md5')
|
|
.update(Buffer.concat([hash2, password]))
|
|
.digest();
|
|
const key = Buffer.concat([hash1, hash2]);
|
|
return [key, iv];
|
|
}
|
|
}
|