Browse Source

fix(rtc,e2ee): fix save/read password process

rcmerci 3 weeks ago
parent
commit
75d44c1d95

+ 58 - 0
src/main/frontend/common/crypt.cljs

@@ -287,6 +287,64 @@
          m)))
    (p/promise m) encrypt-attr-set))
 
+(defn <encrypt-text-by-text-password
+  [text-password text]
+  (assert (and (string? text-password) (string? text)))
+  (p/let [salt (js/crypto.getRandomValues (js/Uint8Array. 16))
+          iv (js/crypto.getRandomValues (js/Uint8Array. 12))
+          password-key (.importKey subtle "raw"
+                                   (.encode (js/TextEncoder.) text-password)
+                                   "PBKDF2"
+                                   false
+                                   #js ["deriveKey"])
+          derived-key (.deriveKey subtle
+                                  #js {:name "PBKDF2"
+                                       :salt salt
+                                       :iterations 100000
+                                       :hash "SHA-256"}
+                                  password-key
+                                  #js {:name "AES-GCM" :length 256}
+                                  true
+                                  #js ["encrypt" "decrypt"])
+          encoded-text (.encode (js/TextEncoder.) text)
+          encrypted-text (.encrypt subtle
+                                   #js {:name "AES-GCM" :iv iv}
+                                   derived-key
+                                   encoded-text)]
+    [salt iv (js/Uint8Array. encrypted-text)]))
+
+(defn <decrypt-text-by-text-password
+  [text-password encrypted-data-vector]
+  (assert (and (string? text-password) (vector? encrypted-data-vector)))
+  (->
+   (p/let [[salt-data iv-data encrypted-data] encrypted-data-vector
+           salt (js/Uint8Array. salt-data)
+           iv (js/Uint8Array. iv-data)
+           encrypted-data (js/Uint8Array. encrypted-data)
+           password-key (.importKey subtle "raw"
+                                    (.encode (js/TextEncoder.) text-password)
+                                    "PBKDF2"
+                                    false
+                                    #js ["deriveKey"])
+           derived-key (.deriveKey subtle
+                                   #js {:name "PBKDF2"
+                                        :salt salt
+                                        :iterations 100000
+                                        :hash "SHA-256"}
+                                   password-key
+                                   #js {:name "AES-GCM" :length 256}
+                                   true
+                                   #js ["encrypt" "decrypt"])
+           decrypted-data (.decrypt subtle
+                                    #js {:name "AES-GCM" :iv iv}
+                                    derived-key
+                                    encrypted-data)]
+     (.decode (js/TextDecoder.) decrypted-data))
+   (p/catch
+    (fn [e]
+      (log/error "decrypt-text-by-text-password" e)
+      (ex-info "decrypt-text-by-text-password" {} e)))))
+
 (comment
   (let [array-buffers-equal?
         (fn [^js/ArrayBuffer buf1 ^js/ArrayBuffer buf2]

+ 3 - 1
src/main/frontend/components/settings.cljs

@@ -36,6 +36,7 @@
             [frontend.version :as fv]
             [goog.object :as gobj]
             [goog.string :as gstring]
+            [lambdaisland.glogi :as log]
             [logseq.db :as ldb]
             [logseq.shui.hooks :as hooks]
             [logseq.shui.ui :as shui]
@@ -1254,7 +1255,8 @@
                                                        token refresh-token user-uuid new-password)
                               (set-reset-password-status! "Password updated successfully!"))
                              (p/catch (fn [e]
-                                        (js/console.error e)))))
+                                        (log/error :reset-password-failed e)
+                                        (set-reset-password-status! "Failed to update password.")))))
              :disabled (string/blank? new-password)}
             "Reset Password")]))])])
 

+ 2 - 2
src/main/frontend/handler/events/rtc.cljs

@@ -4,6 +4,7 @@
             [frontend.components.e2ee :as e2ee]
             [frontend.handler.events :as events]
             [frontend.state :as state]
+            [lambdaisland.glogi :as log]
             [logseq.shui.ui :as shui]
             [promesa.core :as p]))
 
@@ -17,8 +18,7 @@
        (p/resolve! private-key-promise private-key))
      (p/catch
       (fn [error]
-        (prn :debug :read-e2ee-password-failed)
-        (js/console.error error)
+        (log/error :read-e2ee-password-failed error)
         (shui/dialog-open!
          #(e2ee/e2ee-password-to-decrypt-private-key encrypted-private-key private-key-promise refresh-token)
          {:auto-width? true

+ 3 - 17
src/main/frontend/worker/rtc/crypt.cljs

@@ -20,29 +20,15 @@
 
 (defn- <save-e2ee-password
   [refresh-token password]
-  (prn :debug :<save-e2ee-password password)
-  (assert (and (string? refresh-token)
-               (string? password)))
-  (p/let [raw (.encode (js/TextEncoder.) refresh-token)
-          digestbuf (.digest js/crypto.subtle "SHA-256" raw)
-          key-bytes (js/Uint8Array. digestbuf)
-          aes-key (crypt/<import-aes-key key-bytes)
-          result (crypt/<encrypt-text aes-key password)
+  (p/let [result (crypt/<encrypt-text-by-text-password refresh-token password)
           text (ldb/write-transit-str result)]
     (opfs/<write-text! e2ee-password-file text)))
 
 (defn- <read-e2ee-password
   [refresh-token]
-  (prn :debug :<read-e2ee-password)
-  (assert (string? refresh-token))
-  (p/let [raw (.encode (js/TextEncoder.) refresh-token)
-          digestbuf (.digest js/crypto.subtle "SHA-256" raw)
-          key-bytes (js/Uint8Array. digestbuf)
-          aes-key (crypt/<import-aes-key key-bytes)
-          text (opfs/<read-text! e2ee-password-file)
+  (p/let [text (opfs/<read-text! e2ee-password-file)
           data (ldb/read-transit-str text)
-          password (crypt/<decrypt-text aes-key data)]
-    (prn :debug :text text :password password)
+          password (crypt/<decrypt-text-by-text-password refresh-token data)]
     password))
 
 (defn- <get-item