2024-05-16 23:17:06 +03:00
|
|
|
import { CHALLENGE_SECRET } from '$env/static/private';
|
|
|
|
import * as crypto from 'crypto';
|
|
|
|
import { v4 } from 'uuid';
|
|
|
|
|
|
|
|
const IV_LENGTH = 16;
|
|
|
|
const ALGORITHM = 'aes-256-cbc';
|
|
|
|
|
|
|
|
export class CryptoUtils {
|
|
|
|
public static generateString(length: number): string {
|
|
|
|
return crypto.randomBytes(length).toString('hex').slice(0, length);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static generateSecret(): string {
|
|
|
|
return crypto.randomBytes(256 / 8).toString('hex');
|
|
|
|
}
|
|
|
|
|
|
|
|
public static insecureHash(input: string): string {
|
|
|
|
return crypto.createHash('md5').update(input).digest('hex');
|
|
|
|
}
|
|
|
|
|
|
|
|
public static createUUID(): string {
|
|
|
|
return v4();
|
|
|
|
}
|
|
|
|
|
|
|
|
// https://stackoverflow.com/q/52212430
|
|
|
|
/**
|
|
|
|
* Symmetric encryption function
|
|
|
|
* @param text String to encrypt
|
|
|
|
* @param key Encryption key
|
|
|
|
* @returns Encrypted text
|
|
|
|
*/
|
|
|
|
public static encrypt(text: string, key: string): string {
|
|
|
|
const iv = crypto.randomBytes(IV_LENGTH);
|
|
|
|
const cipher = crypto.createCipheriv(ALGORITHM, Buffer.from(key, 'hex'), iv);
|
|
|
|
let encrypted = cipher.update(text);
|
|
|
|
encrypted = Buffer.concat([encrypted, cipher.final()]);
|
|
|
|
return `${iv.toString('hex')}:${encrypted.toString('hex')}`;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Symmetric decryption function
|
|
|
|
* @param text Encrypted string
|
|
|
|
* @param key Decryption key
|
|
|
|
* @returns Decrypted text
|
|
|
|
*/
|
|
|
|
public static decrypt(text: string, key: string): string {
|
|
|
|
const [iv, encryptedText] = text.split(':').map((part) => Buffer.from(part, 'hex'));
|
|
|
|
|
|
|
|
const decipher = crypto.createDecipheriv(ALGORITHM, Buffer.from(key, 'hex'), iv);
|
|
|
|
|
|
|
|
let decrypted = decipher.update(encryptedText);
|
|
|
|
decrypted = Buffer.concat([decrypted, decipher.final()]);
|
|
|
|
return decrypted.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static async encryptChallenge<T>(challenge: T): Promise<string> {
|
|
|
|
return this.encrypt(JSON.stringify(challenge), CHALLENGE_SECRET);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static async decryptChallenge<T>(challenge: string): Promise<T> {
|
|
|
|
return JSON.parse(this.decrypt(challenge, CHALLENGE_SECRET));
|
|
|
|
}
|
2024-05-17 23:22:44 +03:00
|
|
|
|
|
|
|
static safeCompare(token: string, token2: string) {
|
|
|
|
return crypto.timingSafeEqual(Buffer.from(token), Buffer.from(token2));
|
|
|
|
}
|
|
|
|
|
|
|
|
static sha256hash(input: string) {
|
|
|
|
return crypto.createHash('sha256').update(input).digest();
|
|
|
|
}
|
|
|
|
|
|
|
|
static createS256(input: string) {
|
|
|
|
return CryptoUtils.sha256hash(Buffer.from(input).toString('ascii'))
|
|
|
|
.toString('base64')
|
|
|
|
.replace(/\+/g, '-')
|
|
|
|
.replace(/\//g, '_')
|
|
|
|
.replace(/=+$/, '');
|
|
|
|
}
|
2024-05-16 23:17:06 +03:00
|
|
|
}
|