feat: create encryption and otp utils

This commit is contained in:
Nicolas Meienberger 2023-04-06 06:17:16 +02:00
parent 975f5bc536
commit 96bb7e9a3d
3 changed files with 82 additions and 0 deletions

View file

@ -0,0 +1,32 @@
import { faker } from '@faker-js/faker';
import { setConfig } from '../../core/TipiConfig';
import { encrypt, decrypt } from '../encryption';
describe('Test: encrypt', () => {
it('should encrypt the provided data', () => {
// arrange
setConfig('jwtSecret', faker.random.word());
const data = faker.random.word();
const salt = faker.random.word();
// act
const encryptedData = encrypt(data, salt);
// assert
expect(encryptedData).not.toEqual(data);
});
it('should decrypt the provided data', () => {
// arrange
setConfig('jwtSecret', faker.random.word());
const data = faker.random.word();
const salt = faker.random.word();
// act
const encryptedData = encrypt(data, salt);
const decryptedData = decrypt(encryptedData, salt);
// assert
expect(decryptedData).toEqual(data);
});
});

View file

@ -0,0 +1,45 @@
import crypto from 'crypto';
import { getConfig } from '../core/TipiConfig';
const algorithm = 'aes-256-gcm';
const keyLength = 32;
/**
* Given a string, encrypts it using the provided salt
*
* @param {string} data - The data to encrypt
* @param {string} salt - The salt to use to encrypt the data
* @returns {string} - The encrypted data
*/
export const encrypt = (data: string, salt: string) => {
const key = crypto.pbkdf2Sync(getConfig().jwtSecret, salt, 100000, keyLength, 'sha256');
const iv = crypto.randomBytes(12);
const cipher = crypto.createCipheriv(algorithm, key, iv);
const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
const tag = cipher.getAuthTag();
return `${iv.toString('hex')}:${encrypted.toString('hex')}:${tag.toString('hex')}`;
};
/**
* Given an encrypted string, decrypts it using the provided salt
*
* @param {string} encryptedData - The data to decrypt
* @param {string} salt - The salt used to encrypt the data
* @returns {string} - The decrypted data
*/
export const decrypt = (encryptedData: string, salt: string) => {
const key = crypto.pbkdf2Sync(getConfig().jwtSecret, salt, 100000, keyLength, 'sha256');
const parts = encryptedData.split(':');
const iv = Buffer.from(parts.shift() as string, 'hex');
const encrypted = Buffer.from(parts.shift() as string, 'hex');
const tag = Buffer.from(parts.shift() as string, 'hex');
const decipher = crypto.createDecipheriv(algorithm, key, iv);
decipher.setAuthTag(tag);
let decrypted = decipher.update(encrypted);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted.toString();
};

5
src/server/utils/totp.ts Normal file
View file

@ -0,0 +1,5 @@
import { Authenticator } from '@otplib/core';
import { keyDecoder, keyEncoder } from '@otplib/plugin-thirty-two';
import { createDigest, createRandomBytes } from '@otplib/plugin-crypto';
export const TotpAuthenticator = new Authenticator({ createDigest, createRandomBytes, keyEncoder, keyDecoder });