| |
| |
| |
| |
|
|
| |
| |
| |
| |
| export function encryptData(plainText: string, secretKey: string): string { |
| const salt = "HBT-SECURE-VAULT-" + secretKey.length; |
| const combined = salt + "||" + plainText; |
| |
| |
| let pad = 0; |
| for (let i = 0; i < secretKey.length; i++) { |
| pad += secretKey.charCodeAt(i); |
| } |
| |
| |
| const chars: string[] = []; |
| for (let i = 0; i < combined.length; i++) { |
| let charCode = combined.charCodeAt(i); |
| |
| charCode = (charCode + pad + i) % 65535; |
| chars.push(String.fromCharCode(charCode)); |
| } |
| |
| const scrambled = chars.join(''); |
| |
| try { |
| return btoa(unescape(encodeURIComponent(scrambled))); |
| } catch (e) { |
| |
| return btoa(scrambled); |
| } |
| } |
|
|
| |
| |
| |
| |
| export function decryptData(cipherText: string, secretKey: string): string { |
| let scrambled = ''; |
| try { |
| scrambled = decodeURIComponent(escape(atob(cipherText))); |
| } catch (e) { |
| try { |
| scrambled = atob(cipherText); |
| } catch (err) { |
| throw new Error("Invalid file structure: Decryption failed."); |
| } |
| } |
|
|
| let pad = 0; |
| for (let i = 0; i < secretKey.length; i++) { |
| pad += secretKey.charCodeAt(i); |
| } |
|
|
| const chars: string[] = []; |
| for (let i = 0; i < scrambled.length; i++) { |
| let charCode = scrambled.charCodeAt(i); |
| |
| charCode = (charCode - pad - i) % 65535; |
| while (charCode < 0) charCode += 65535; |
| chars.push(String.fromCharCode(charCode)); |
| } |
|
|
| const decrypted = chars.join(''); |
| |
| if (!decrypted.includes("||")) { |
| throw new Error("Invalid password: Secure decryption key mismatch."); |
| } |
|
|
| const parts = decrypted.split("||"); |
| const salt = parts[0]; |
| const payload = parts.slice(1).join("||"); |
|
|
| if (!salt.startsWith("HBT-SECURE-VAULT-")) { |
| throw new Error("Corrupted backup data block."); |
| } |
|
|
| return payload; |
| } |
|
|