ソースを参照

Encrypt create account data.

Lee Morgan 11 ヶ月 前
コミット
db589a2032

+ 27 - 4
src/views/js/EncryptionHandler.js

@@ -5,7 +5,8 @@ export default class EncryptionHandler {
 
     static async create(password, salt){
         const key = await EncryptionHandler.generateEncryptionKey(password, salt);
-        localStorage.setItem("key", key);
+        const raw = await crypto.subtle.exportKey("raw", key);
+        localStorage.setItem("key", btoa(String.fromCharCode(...new Uint8Array(raw))));
         return new EncryptionHandler(key);
     }
 
@@ -50,6 +51,13 @@ export default class EncryptionHandler {
         return btoa(String.fromCharCode(...iv));
     }
 
+    generateIv(){
+        const length = 12;
+        const iv = new Uint8Array(length);
+        crypto.getRandomValues(iv);
+        return btoa(String.fromCharCode(...iv));
+    }
+
     stringToBuffer(str){
         return Uint8Array.from(atob(str), c => c.charCodeAt(0));
     }
@@ -80,17 +88,32 @@ export default class EncryptionHandler {
         );
     }
 
+    static async getKeyFromStorage(){
+        let key = localStorage.getItem("key");
+        if(!key) throw null;
+
+        const raw = Uint8Array.from(atob(key), c => c.charCodeAt(0));
+        return crypto.subtle.importKey(
+            "raw",
+            raw,
+            {name: "AES-GCM"},
+            true,
+            ["encrypt", "decrypt"]
+        );
+    }
+
     async encrypt(data, iv){
         const json = JSON.stringify(data);
-        const buff = new TextEncoder().encode(str);
+        const buff = new TextEncoder().encode(data);
+        const buffIv = new TextEncoder().encode(iv);
 
         const encrypted = await crypto.subtle.encrypt(
             {
                 name: "AES-GCM",
-                iv
+                iv: buffIv
             },
             this._key,
-            data
+            buff
         );
 
         return btoa(String.fromCharCode(...new Uint8Array(encrypted)));

+ 4 - 2
src/views/js/index.js

@@ -31,8 +31,6 @@ fetch("/api/user", {
     .then(r=>r.json())
     .then((response)=>{
         if(response.error) throw response;
-        let key = localStorage.getItem("key");
-        if(!key) throw null;
 
         window.user = new User(
             response.id,
@@ -41,6 +39,10 @@ fetch("/api/user", {
             response.accounts
         );
 
+
+        return EncryptionHandler.getKeyFromStorage();
+    })
+    .then((key)=>{
         window.encryptionHandler = new EncryptionHandler(key);
         currentPage = new Home();
     })

+ 11 - 3
src/views/js/pages/CreateAccount.js

@@ -8,15 +8,21 @@ export default class CreateAccount extends Page{
         this.render();
     }
 
-    submit(event){
+    async submit(){
         event.preventDefault();
-        console.log("submit");
+
+        const data = {
+            name: this.container.querySelector(".name").value,
+            balance: this.container.querySelector(".balance").value
+        };
+        const iv = encryptionHandler.generateIv();
+        const encryptedData = await encryptionHandler.encrypt(data, iv);
     }
 
     render(){
         new Elem("form")
             .addClass("standardForm")
-            .onsubmit(this.submit.bind())
+            .onsubmit(this.submit.bind(this))
             .append(new Elem("h1")
                 .text("Create Account")
             )
@@ -24,6 +30,7 @@ export default class CreateAccount extends Page{
                 .text("Account Name")
                 .append(new Elem("input")
                     .type("text")
+                    .addClass("name")
                     .placeholder("Account Name")
                     .required()
                     .focus()
@@ -33,6 +40,7 @@ export default class CreateAccount extends Page{
                 .text("Current Balance")
                 .append(new Elem("input")
                     .type("number")
+                    .addClass("balance")
                     .placeholder("Current Balance")
                     .min("0")
                     .step("0.01")