From 6314d8f6e69f6dc3baca2910d03bd238c2e079a4 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Sat, 26 Apr 2025 12:27:44 -0400 Subject: [PATCH] Now with first version of encryption! --- src/lib/ae_utils/ae_utils.ts | 3 + src/lib/ae_utils/ae_utils__crypto.ts | 30 +++++++ .../ae_comp__journal_entry_obj_id_view.svelte | 79 +++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 src/lib/ae_utils/ae_utils__crypto.ts diff --git a/src/lib/ae_utils/ae_utils.ts b/src/lib/ae_utils/ae_utils.ts index 6e2818f0..ecc42b1e 100644 --- a/src/lib/ae_utils/ae_utils.ts +++ b/src/lib/ae_utils/ae_utils.ts @@ -10,6 +10,7 @@ import { to_title_case } from './ae_utils__to_title_case'; import { process_data_string } from './ae_utils__process_data_string'; import { set_obj_prop_display_name } from './ae_utils__set_obj_prop_display_name'; import { return_obj_type_path } from './ae_utils__return_obj_type_path'; +import { encrypt_content, decrypt_content } from './ae_utils__crypto'; export type key_str = { @@ -263,4 +264,6 @@ export let ae_util = { file_extension_icon: file_extension_icon, set_obj_prop_display_name: set_obj_prop_display_name, return_obj_type_path: return_obj_type_path, + encrypt_content: encrypt_content, + decrypt_content: decrypt_content, }; diff --git a/src/lib/ae_utils/ae_utils__crypto.ts b/src/lib/ae_utils/ae_utils__crypto.ts new file mode 100644 index 00000000..919b6ade --- /dev/null +++ b/src/lib/ae_utils/ae_utils__crypto.ts @@ -0,0 +1,30 @@ +async function generate_iv() { + const data = new Uint8Array(16); + crypto.getRandomValues(data); + return data; +} + + +export let encrypt_content = async function encrypt_content( + content: string, keyData: string + ) { + const iv = await generate_iv(); + const keyBytes = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(keyData)); + const key = await crypto.subtle.importKey('raw', keyBytes, { name: 'AES-CBC' }, false, ['encrypt']); + const encodedContent = await crypto.subtle.encrypt({ name: 'AES-CBC', iv }, key, new TextEncoder().encode(content)); + const base64 = btoa(String.fromCharCode(...new Uint8Array(encodedContent))); + console.log('Base64 Encoded Content:', base64); + return { base64, iv }; +} + +export let decrypt_content = async function decrypt_content( + base64Content: string, iv: Uint8Array, keyData: string + ) { + const keyBytes = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(keyData)); + const key = await crypto.subtle.importKey('raw', keyBytes, { name: 'AES-CBC' }, false, ['decrypt']); + const encryptedContent = Uint8Array.from(atob(base64Content), c => c.charCodeAt(0)); + const decryptedContent = await crypto.subtle.decrypt({ name: 'AES-CBC', iv }, key, encryptedContent); + const decodedContent = new TextDecoder().decode(decryptedContent); + // console.log('Decrypted Content:', decodedContent); + return decodedContent; +} \ No newline at end of file diff --git a/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte b/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte index e174c22d..2332af2c 100644 --- a/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte +++ b/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte @@ -209,6 +209,74 @@ async function change_journal_id() { $journals_slct.journal_id = tmp_entry_obj?.journal_id; goto(`/journals/${tmp_entry_obj?.journal_id}`); } + + +// async function generate_iv() { +// const data = new Uint8Array(16); +// crypto.getRandomValues(data); +// return data; +// } + +// async function encrypt_content(content, keyData) { +// const iv = await generate_iv(); +// const keyBytes = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(keyData)); +// const key = await crypto.subtle.importKey('raw', keyBytes, { name: 'AES-CBC' }, false, ['encrypt']); +// const encodedContent = await crypto.subtle.encrypt({ name: 'AES-CBC', iv }, key, new TextEncoder().encode(content)); +// const base64 = btoa(String.fromCharCode(...new Uint8Array(encodedContent))); +// console.log('Base64 Encoded Content:', base64); +// return { base64, iv }; +// } + +// async function decrypt_content(base64Content, iv, keyData) { +// const keyBytes = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(keyData)); +// const key = await crypto.subtle.importKey('raw', keyBytes, { name: 'AES-CBC' }, false, ['decrypt']); +// const encryptedContent = Uint8Array.from(atob(base64Content), c => c.charCodeAt(0)); +// const decryptedContent = await crypto.subtle.decrypt({ name: 'AES-CBC', iv }, key, encryptedContent); +// const decodedContent = new TextDecoder().decode(decryptedContent); +// console.log('Decrypted Content:', decodedContent); +// return decodedContent; +// } + +// Example usage +(async () => { + const keyData = "my-secret-key"; + const content = "This is my test content to encrypt and decrypt."; + + const { base64, iv } = await ae_util.encrypt_content(content, keyData); + await ae_util.decrypt_content(base64, iv, keyData); +})(); + +const test_key = "my-secret-key"; +let content = "This is my test content to encrypt and decrypt."; +let test_encrypted_base64: string = $state(''); +let test_iv: null|Uint8Array = $state(null); +let test_decrypted: string = $state(''); + +$effect(async () => { + if ($lq__journal_entry_obj?.content) { + content = $lq__journal_entry_obj?.content; + + let encrypted_base64 = await ae_util.encrypt_content(content, test_key); + test_encrypted_base64 = encrypted_base64.base64; + test_iv = encrypted_base64.iv; + // test_encrypted = base64; + + // base64.then((result) => { + // test_encrypted = result; + // console.log('Encrypted content:', test_encrypted); + // }).catch((error) => { + // console.error('Error encrypting content:', error); + // }); + + let decrypted = await ae_util.decrypt_content(test_encrypted_base64, test_iv, test_key); + test_decrypted = decrypted; + if (log_lvl) { + console.log('Decrypted content:', test_decrypted); + } + } + // console.log('Encrypted content:', base64); + // console.log('IV:', iv); +}); @@ -706,6 +774,17 @@ async function change_journal_id() { > {@html $lq__journal_entry_obj?.content_md_html} + + + +