From da5b74b5f17e588b28878885427a413b391751d9 Mon Sep 17 00:00:00 2001 From: blek Date: Mon, 11 Sep 2023 22:37:53 +1000 Subject: [PATCH] V1 cipher --- src/lib/cipher.ts | 61 ++++++++++++++++++++++++++++++++++++++ src/lib/scriptinterface.ts | 4 ++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/lib/cipher.ts b/src/lib/cipher.ts index f1bdc5a..69f22b8 100644 --- a/src/lib/cipher.ts +++ b/src/lib/cipher.ts @@ -1,5 +1,66 @@ import { random } from "./random"; +export async function bufferToBase64(buffer: BufferSource) { + const base64url: string = await new Promise(r => { + const reader = new FileReader() + // @ts-expect-error + reader.onload = () => r(reader.result) + reader.readAsDataURL(new Blob([buffer])) + }); + + return base64url.slice(base64url.indexOf(',') + 1); + } + +export class AES256 { + static async str2key(key: string): Promise { + if (key.length > 32) + throw new Error('Key must not be longer than 32 characters!'); + + return crypto.subtle.importKey( + 'raw', + new TextEncoder().encode(key.padEnd(32, '0')), + 'AES-CBC', + true, + [ 'encrypt', 'decrypt' ] + ); + } + + static async encode(data: Uint8Array, secret: string): Promise { + const key = await this.str2key(secret); + return crypto.subtle.encrypt({ name: 'AES-CBC', iv: new Uint8Array(16).fill(0) }, key, data); + } + + static async encodeStr(text: string, secret: string): Promise { + return this.encode(new TextEncoder().encode(text), secret); + } + + static async decode(data: ArrayBuffer, secret: string): Promise { + const key = await this.str2key(secret); + return crypto.subtle.decrypt({ name: 'AES-CBC', iv: new Uint8Array(16).fill(0) }, key, data); + } + + static async decodeToStr(data: ArrayBuffer, secret: string): Promise { + return new TextDecoder().decode(await this.decode(data, secret)); + } +} + +export class V1 { + + // sssshhh.. dont tell anyone :p + static aes256secret = 'skater_girl'; + + static async encode(word: string): Promise { + let scrambled = ''; + for (const letter of word) { + scrambled += String.fromCharCode(random(32, 128)) + letter; + } + + return { + data: await bufferToBase64(await AES256.encodeStr(scrambled, this.aes256secret)) + } + } +} + export function encode(word: string) { let out = ''; for (const letter of word) { diff --git a/src/lib/scriptinterface.ts b/src/lib/scriptinterface.ts index 421b4a0..5d117ea 100644 --- a/src/lib/scriptinterface.ts +++ b/src/lib/scriptinterface.ts @@ -1,5 +1,6 @@ import { random } from "./random"; -import { encode, decode } from "./cipher"; +import { encode, decode, V1 } from "./cipher"; +import * as cipher from './cipher'; let allowHooks: {(): void}[] = []; @@ -43,6 +44,7 @@ export class WordleLibrary { readonly random = random; readonly encode = encode; readonly decode = decode; + readonly cipher = cipher; } export class ScriptInterface {