Fix encryption logic (#4672)

Co-authored-by: Thomas Trompette <thomast@twenty.com>
This commit is contained in:
Thomas Trompette 2024-03-26 17:43:32 +01:00 committed by GitHub
parent d4eb75abff
commit f08dfec00a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 29 additions and 37 deletions

View File

@ -1,4 +1,9 @@
import { createCipheriv, createDecipheriv, createHash } from 'crypto'; import {
createCipheriv,
createDecipheriv,
createHash,
randomBytes,
} from 'crypto';
import * as bcrypt from 'bcrypt'; import * as bcrypt from 'bcrypt';
@ -16,41 +21,34 @@ export const compareHash = async (password: string, passwordHash: string) => {
return bcrypt.compare(password, passwordHash); return bcrypt.compare(password, passwordHash);
}; };
export const encryptText = ( export const encryptText = (textToEncrypt: string, key: string): string => {
textToEncrypt: string,
key: string,
iv: string,
): string => {
const keyHash = createHash('sha512') const keyHash = createHash('sha512')
.update(key) .update(key)
.digest('hex') .digest('hex')
.substring(0, 32); .substring(0, 32);
const ivHash = createHash('sha512').update(iv).digest('hex').substring(0, 16); const iv = randomBytes(16);
const cipher = createCipheriv('aes-256-ctr', keyHash, ivHash); const cipher = createCipheriv('aes-256-ctr', keyHash, iv);
return Buffer.concat([cipher.update(textToEncrypt), cipher.final()]).toString(
'base64',
);
};
export const decryptText = (
textToDecrypt: string,
key: string,
iv: string,
): string => {
const keyHash = createHash('sha512')
.update(key)
.digest('hex')
.substring(0, 32);
const ivHash = createHash('sha512').update(iv).digest('hex').substring(0, 16);
const decipher = createDecipheriv('aes-256-ctr', keyHash, ivHash);
return Buffer.concat([ return Buffer.concat([
decipher.update(Buffer.from(textToDecrypt, 'base64')), iv,
decipher.final(), cipher.update(textToEncrypt),
]).toString(); cipher.final(),
]).toString('base64');
};
export const decryptText = (textToDecrypt: string, key: string): string => {
const textBuffer = Buffer.from(textToDecrypt, 'base64');
const iv = textBuffer.subarray(0, 16);
const text = textBuffer.subarray(16);
const keyHash = createHash('sha512')
.update(key)
.digest('hex')
.substring(0, 32);
const decipher = createDecipheriv('aes-256-ctr', keyHash, iv);
return Buffer.concat([decipher.update(text), decipher.final()]).toString();
}; };

View File

@ -53,8 +53,6 @@ export class RemoteServerService<T extends RemoteServerType> {
const encryptedPassword = await encryptText( const encryptedPassword = await encryptText(
remoteServerInput.userMappingOptions.password, remoteServerInput.userMappingOptions.password,
key, key,
// TODO: check if we should use a separated IV
key,
); );
remoteServerToCreate = { remoteServerToCreate = {

View File

@ -17,11 +17,7 @@ export const buildPostgresUrl = (
const foreignDataWrapperOptions = remoteServer.foreignDataWrapperOptions; const foreignDataWrapperOptions = remoteServer.foreignDataWrapperOptions;
const userMappingOptions = remoteServer.userMappingOptions; const userMappingOptions = remoteServer.userMappingOptions;
const password = decryptText( const password = decryptText(userMappingOptions.password, secretKey);
userMappingOptions.password,
secretKey,
secretKey,
);
const url = `postgres://${userMappingOptions.username}:${password}@${foreignDataWrapperOptions.host}:${foreignDataWrapperOptions.port}/${foreignDataWrapperOptions.dbname}`; const url = `postgres://${userMappingOptions.username}:${password}@${foreignDataWrapperOptions.host}:${foreignDataWrapperOptions.port}/${foreignDataWrapperOptions.dbname}`;