Spaces:
Sleeping
Sleeping
File size: 2,097 Bytes
521a9b6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | import * as crypto from 'crypto';
import { config } from '../config';
const ALGORITHM = 'aes-256-gcm';
const IV_LENGTH = 16;
const AUTH_TAG_LENGTH = 16;
/**
* Derive a 32-byte key from the encryption key string.
* Uses SHA-256 so any length passphrase works.
*/
function deriveKey(): Buffer {
return crypto.createHash('sha256').update(config.credentialEncryptionKey).digest();
}
/**
* Encrypt a plaintext password.
* Returns base64 string: iv(16) + authTag(16) + ciphertext
*/
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();
// Format: iv + authTag + ciphertext
const combined = Buffer.concat([iv, authTag, encrypted]);
return combined.toString('base64');
}
/**
* Decrypt an encrypted password string.
* Input is base64 string: iv(16) + authTag(16) + ciphertext
*/
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');
}
/**
* Get the Turnitin password for an account.
* If encryption key is set, tries to decrypt. Otherwise uses shared password.
*/
export function getAccountPassword(encryptedPassword?: string | null): string {
if (encryptedPassword && config.credentialEncryptionKey) {
try {
return decryptPassword(encryptedPassword);
} catch {
// Fallback to shared password if decryption fails
}
}
return config.turnitinSharedPassword;
}
|