]> git.ardis.lu - static-encrypt/commitdiff
Move decrypt into its own module
authorArdis Lu <ardisglu@gmail.com>
Tue, 21 Feb 2023 06:33:54 +0000 (22:33 -0800)
committerArdis Lu <ardisglu@gmail.com>
Tue, 21 Feb 2023 06:33:54 +0000 (22:33 -0800)
So there can be custom decryption frontends

decrypt.js [new file with mode: 0644]
index.html
template.html

diff --git a/decrypt.js b/decrypt.js
new file mode 100644 (file)
index 0000000..9132f5c
--- /dev/null
@@ -0,0 +1,42 @@
+export default async function decrypt(content, password) {
+  const encodedPassword = new TextEncoder().encode(password);
+
+  const contentBuffer = Uint8Array.from(atob(content), c => c.charCodeAt(0));
+  const salt = new Uint8Array(32);
+  const iv = new Uint8Array(32);
+  const ciphertext = new Uint8Array(contentBuffer.byteLength - 64);
+  salt.set(contentBuffer.slice(0, 32));
+  iv.set(contentBuffer.slice(32, 64));
+  ciphertext.set(contentBuffer.slice(64));
+
+  const keyMaterial = await crypto.subtle.importKey(
+    'raw',
+    encodedPassword,
+    'PBKDF2',
+    false,
+    ['deriveKey'],
+  );
+
+  const key = await crypto.subtle.deriveKey(
+    {
+      name: 'PBKDF2',
+      hash: 'SHA-512',
+      salt,
+      iterations: 400_000,
+    },
+    keyMaterial,
+    { name: 'AES-GCM', length: 256 },
+    false,
+    ['decrypt']
+  );
+
+  const encodedPlaintext = new Uint8Array(await crypto.subtle.decrypt(
+    { name: 'AES-GCM', iv },
+    key,
+    ciphertext,
+  ));
+
+  const plaintext = new TextDecoder().decode(encodedPlaintext);
+
+  return plaintext;
+}
index d607f8e2b0b2929256ff71fab53b48df8a39f968..8fe387488cb1a20a7b512f78cf77f9deee845f1e 100644 (file)
       return content;
     }
 
+    const { default: decrypt } = await import('/decrypt.js');
     const template = await fetch('/template.html').then(r => r.text());
     document.querySelector('form').addEventListener('submit', async e => {
       e.preventDefault();
       const password = data.get('password');
 
       const encrypted = await encrypt(content, password);
-      const output = template.replace("const content = 'DO_NOT_MODIFY_THIS_LINE';", `const content = '${encrypted}';`);
+      const scriptInjection = `<script>const content = '${encrypted}'; ${decrypt.toString()}<\/script>`;
+      const output = template.replace('<!-- SCRIPT INJECTION -->', scriptInjection);
       e.target.elements.output.textContent = output;
     });
   </script>
index fea5190845d13c1227fd7f077590211f7b0adb66..4ca08fabb6454f1f74c5c38d9ca6d94f1af65510 100644 (file)
     </form>
   </main>
 
+  <!-- SCRIPT INJECTION -->
   <script>
-    const content = 'DO_NOT_MODIFY_THIS_LINE';
-
-    async function decrypt(content, password) {
-      const encoder = new TextEncoder();
-      const encodedPassword = encoder.encode(password);
-
-      const contentBuffer = Uint8Array.from(atob(content), c => c.charCodeAt(0));
-      const salt = new Uint8Array(32);
-      const iv = new Uint8Array(32);
-      const ciphertext = new Uint8Array(contentBuffer.byteLength - 64);
-      salt.set(contentBuffer.slice(0, 32));
-      iv.set(contentBuffer.slice(32, 64));
-      ciphertext.set(contentBuffer.slice(64));
-
-      const keyMaterial = await crypto.subtle.importKey(
-        'raw',
-        encodedPassword,
-        'PBKDF2',
-        false,
-        ['deriveKey'],
-      );
-
-      const key = await crypto.subtle.deriveKey(
-        {
-          name: 'PBKDF2',
-          hash: 'SHA-512',
-          salt,
-          iterations: 400_000,
-        },
-        keyMaterial,
-        { 'name': 'AES-GCM', 'length': 256 },
-        false,
-        ['decrypt']
-      );
-
-      const encodedPlaintext = new Uint8Array(await crypto.subtle.decrypt(
-        { name: 'AES-GCM', iv },
-        key,
-        ciphertext,
-      ));
-
-      const plaintext = new TextDecoder().decode(encodedPlaintext);
-
-      return plaintext;
-    }
-
     document.querySelector('form').addEventListener('submit', async e => {
       e.preventDefault();
+      const password = new FormData(e.target).get('password');
+      const newDocument = await decrypt(content, password);
       
-      const data = new FormData(e.target);
-      const password = data.get('password');
-
-      document.querySelector('html').innerHTML = await decrypt(content, password);
+      document.open();
+      document.write(newDocument);
+      document.close();
     });
   </script>
 </body>
This page took 0.040324 seconds and 4 git commands to generate.