| import * as crypto from 'crypto'; |
| import { config } from '../config'; |
|
|
| const ALGORITHM = 'aes-256-gcm'; |
| const IV_LENGTH = 16; |
| const AUTH_TAG_LENGTH = 16; |
|
|
| |
| |
| |
| |
| function deriveKey(): Buffer { |
| return crypto.createHash('sha256').update(config.credentialEncryptionKey).digest(); |
| } |
|
|
| |
| |
| |
| |
| export function encryptPassword(plaintext: string): string { |
| const key = deriveKey(); |
| const iv = crypto.randomBytes(IV_LENGTH); |
| const cipher = crypto.createCipheriv(ALGORITHM, key, iv); |
|
|
| const encrypted = Buffer.concat([ |
| cipher.update(plaintext, 'utf8'), |
| cipher.final(), |
| ]); |
|
|
| const authTag = cipher.getAuthTag(); |
|
|
| |
| const combined = Buffer.concat([iv, authTag, encrypted]); |
| return combined.toString('base64'); |
| } |
|
|
| |
| |
| |
| |
| export function decryptPassword(encrypted: string): string { |
| const key = deriveKey(); |
| const combined = Buffer.from(encrypted, 'base64'); |
|
|
| const iv = combined.subarray(0, IV_LENGTH); |
| const authTag = combined.subarray(IV_LENGTH, IV_LENGTH + AUTH_TAG_LENGTH); |
| const ciphertext = combined.subarray(IV_LENGTH + AUTH_TAG_LENGTH); |
|
|
| const decipher = crypto.createDecipheriv(ALGORITHM, key, iv); |
| decipher.setAuthTag(authTag); |
|
|
| const decrypted = Buffer.concat([ |
| decipher.update(ciphertext), |
| decipher.final(), |
| ]); |
|
|
| return decrypted.toString('utf8'); |
| } |
|
|
| |
| |
| |
| |
| export function getAccountPassword(encryptedPassword?: string | null): string { |
| if (encryptedPassword && config.credentialEncryptionKey) { |
| try { |
| return decryptPassword(encryptedPassword); |
| } catch { |
| |
| } |
| } |
| return config.turnitinSharedPassword; |
| } |
|
|