Path: blob/main/components/gitpod-protocol/src/encryption/encryption-engine.ts
2500 views
/**1* Copyright (c) 2020 Gitpod GmbH. All rights reserved.2* Licensed under the GNU Affero General Public License (AGPL).3* See License.AGPL.txt in the project root for license information.4*/5import "reflect-metadata";67import * as crypto from "crypto";8import { injectable } from "inversify";910export interface KeyParams {11iv: string;12}1314export interface EncryptedData {15/** utf8 encoded string */16data: string;17keyParams: KeyParams;18}1920export const EncryptionEngine = Symbol("EncryptionEngine");21export interface EncryptionEngine {22/**23* @param data utf8 encoded string24*/25encrypt(data: string, key: Buffer): EncryptedData;26decrypt(encryptedData: EncryptedData, key: Buffer): string;27}2829/**30* For starters, let's use aes-cbc-256 with:31* - 16 bytes/128 bits IV (the size of an aes-256-cbc block)32* - no salt, as we pass in a real key (no salting needed to turn a password into a key)33* The implementation closely follows the exampes in https://nodejs.org/api/crypto.html.34*/35@injectable()36export class EncryptionEngineImpl {37readonly algorithm = "aes-256-cbc";38readonly enc = "base64";3940encrypt(data: string, key: Buffer): EncryptedData {41const iv = crypto.randomBytes(16);42const cipher = crypto.createCipheriv(this.algorithm, key, iv);43const encrypted = cipher.update(Buffer.from(data, "utf8"));44const finalEncrypted = Buffer.concat([encrypted, cipher.final()]);45return {46data: finalEncrypted.toString(this.enc),47keyParams: {48iv: iv.toString(this.enc),49},50};51}5253decrypt(encryptedData: EncryptedData, key: Buffer): string {54const decipher = crypto.createDecipheriv(55this.algorithm,56key,57Buffer.from(encryptedData.keyParams.iv, this.enc),58);59const decrypted = decipher.update(Buffer.from(encryptedData.data, this.enc));60const finalDecrypted = Buffer.concat([decrypted, decipher.final()]);61return finalDecrypted.toString("utf8");62}63}646566