Files
code-box/utils/encryption.ts
2025-01-26 10:02:53 +08:00

102 lines
2.3 KiB
TypeScript

import * as CryptoJS from "crypto-js"
export interface EncryptionInterface {
getEncryptedString(data: string): string
decryptSecretString(secret: string): string | null
decryptEncSecret(entry: any): any | null
getEncryptionStatus(): boolean
updateEncryptionPassword(password: string): void
setEncryptionKeyId(id: string): void
getEncryptionKeyId(): string
}
export class Encryption implements EncryptionInterface {
private password: string
private keyId: string
constructor(hash: string, keyId: string) {
this.password = hash
this.keyId = keyId
}
getEncryptedString(data: string): string {
if (!this.password) {
return data
}
return CryptoJS.AES.encrypt(data, this.password).toString()
}
decryptSecretString(secret: string): string | null {
try {
if (!this.password) {
return secret
}
const decryptedSecret = CryptoJS.AES.decrypt(
secret,
this.password
).toString(CryptoJS.enc.Utf8)
if (!decryptedSecret) {
return null
}
if (decryptedSecret.length < 8) {
return null
}
// Validate secret format
if (
!/^[A-Z2-7]+=*$/i.test(decryptedSecret) && // Base32 format
!/^[0-9a-f]+$/i.test(decryptedSecret) && // Hex format
!/^blz-/.test(decryptedSecret) && // Blizzard format
!/^bliz-/.test(decryptedSecret) && // Alternative Blizzard format
!/^stm-/.test(decryptedSecret) // Steam format
) {
return null
}
return decryptedSecret
} catch (error) {
return null
}
}
decryptEncSecret(entry: any): any | null {
try {
if (!entry.encData || !this.password) {
return null
}
const decryptedData = CryptoJS.AES.decrypt(
entry.encData,
this.password
).toString(CryptoJS.enc.Utf8)
if (!decryptedData) {
return null
}
return JSON.parse(decryptedData)
} catch (error) {
return null
}
}
getEncryptionStatus(): boolean {
return Boolean(this.password)
}
updateEncryptionPassword(password: string): void {
this.password = password
}
setEncryptionKeyId(id: string): void {
this.keyId = id
}
getEncryptionKeyId(): string {
return this.keyId
}
}