UNPKG

@xec-sh/cli

Version:

Xec: The Universal Shell for TypeScript

81 lines 2.57 kB
import { promisify } from 'util'; import { scrypt, createHash, randomBytes, createCipheriv, createDecipheriv } from 'crypto'; const scryptAsync = promisify(scrypt); const ALGORITHM = 'aes-256-gcm'; const SALT_LENGTH = 32; const IV_LENGTH = 16; const TAG_LENGTH = 16; const KEY_LENGTH = 32; const SCRYPT_OPTIONS = { N: 16384, r: 8, p: 1, }; export async function deriveKey(machineId, salt, passphrase) { const secret = passphrase ? `${machineId}:${passphrase}` : machineId; const key = await scryptAsync(secret, salt, KEY_LENGTH); return key; } export async function encrypt(value, machineId, passphrase) { const salt = randomBytes(SALT_LENGTH); const iv = randomBytes(IV_LENGTH); const key = await deriveKey(machineId, salt, passphrase); const cipher = createCipheriv(ALGORITHM, key, iv); const encrypted = Buffer.concat([ cipher.update(value, 'utf8'), cipher.final() ]); const authTag = cipher.getAuthTag(); return { encrypted, salt, iv, authTag }; } export async function decrypt(encrypted, salt, iv, authTag, machineId, passphrase) { const key = await deriveKey(machineId, salt, passphrase); const decipher = createDecipheriv(ALGORITHM, key, iv); decipher.setAuthTag(authTag); const decrypted = Buffer.concat([ decipher.update(encrypted), decipher.final() ]); return decrypted.toString('utf8'); } export function hashKey(key) { return createHash('sha256').update(key).digest('hex'); } export function createFingerprint(data) { const hash = createHash('sha256'); hash.update(typeof data === 'string' ? Buffer.from(data) : data); return hash.digest('hex').substring(0, 16); } export function encode(buffer) { return buffer.toString('base64'); } export function decode(data) { return Buffer.from(data, 'base64'); } export function secureCompare(a, b) { if (a.length !== b.length) { return false; } let result = 0; for (let i = 0; i < a.length; i++) { result |= a.charCodeAt(i) ^ b.charCodeAt(i); } return result === 0; } export function generateSecret(length = 32) { if (length <= 0) { throw new Error('Length must be greater than 0'); } if (length > 1024) { throw new Error('Length must be less than or equal to 1024'); } const bytesNeeded = Math.ceil(length * 3 / 4); const randomData = randomBytes(bytesNeeded); return randomData.toString('base64').substring(0, length); } //# sourceMappingURL=crypto.js.map