Ver Fonte

rtc: transact salt into db before upload-graph

rcmerci há 1 mês atrás
pai
commit
93389d31d6

+ 36 - 36
src/main/frontend/worker/rtc/encrypt.cljs

@@ -6,7 +6,7 @@
   (let [binary (apply str (map js/String.fromCharCode (js/Uint8Array. buffer)))]
     (js/btoa binary)))
 
-(defn- base64->array-buffer [base64]
+(defn base64->array-buffer [base64]
   (let [binary-string (js/atob base64)
         len (.-length binary-string)
         bytes' (js/Uint8Array. len)]
@@ -17,10 +17,17 @@
 (def ^:private encoder (js/TextEncoder.))
 (def ^:private decoder (js/TextDecoder.))
 
-(defn- <salt+password->key
+(defn gen-salt
+  []
+  (array-buffer->base64 (js/crypto.getRandomValues (js/Uint8Array. 16))))
+
+(defn <salt+password->key
   [salt password]
-  (assert (instance? js/Uint8Array salt))
-  (p/let [key-material (js/crypto.subtle.importKey
+  (p/let [salt' (cond
+                  (string? salt) (base64->array-buffer salt)
+                  (instance? js/Uint8Array salt) salt
+                  :else (throw (ex-info "invalid salt value" {:value salt})))
+          key-material (js/crypto.subtle.importKey
                         "raw"
                         (.encode encoder password)
                         #js {:name "PBKDF2"}
@@ -28,40 +35,35 @@
                         #js ["deriveKey"])]
     (js/crypto.subtle.deriveKey
      #js {:name "PBKDF2"
-          :salt salt
+          :salt salt'
           :iterations 100000
           :hash "SHA-256"}
      key-material
      #js {:name "AES-GCM" :length 256}
-     true
+     false
      #js ["encrypt" "decrypt"])))
 
-(defn <gen-encrypt-text-fn
-  [salt password]
-  (p/let [key' (<salt+password->key salt password)]
-    (fn <encrypt-text [plaintext]
-      (p/let [iv (js/crypto.getRandomValues (js/Uint8Array. 12))
-              data (.encode encoder plaintext)
-              encrypted-data (js/crypto.subtle.encrypt
-                              #js {:name "AES-GCM"
-                                   :iv iv}
-                              key'
-                              data)]
-        [iv (js/Uint8Array. encrypted-data)]))))
+(defn <encrypt-text
+  [key' plaintext]
+  (p/let [iv (js/crypto.getRandomValues (js/Uint8Array. 12))
+          data (.encode encoder plaintext)
+          encrypted-data (js/crypto.subtle.encrypt
+                          #js {:name "AES-GCM"
+                               :iv iv}
+                          key'
+                          data)]
+    [iv (js/Uint8Array. encrypted-data)]))
 
-(defn <gen-decrypt-text-fn
-  [salt password]
-  (assert (instance? js/Uint8Array salt))
-  (p/let [key' (<salt+password->key salt password)]
-    (fn <decrypt-text [encrypted-package]
-      (let [[iv ciphertext] encrypted-package]
-        (assert (and (some? iv) (some? ciphertext)))
-        (p/let [decrypted-data (js/crypto.subtle.decrypt
-                                #js {:name "AES-GCM"
-                                     :iv iv}
-                                key'
-                                ciphertext)]
-          (.decode decoder decrypted-data))))))
+(defn <decrypt-text
+  [key' encrypted-package]
+  (let [[iv ciphertext] encrypted-package]
+    (assert (and (some? iv) (some? ciphertext)))
+    (p/let [decrypted-data (js/crypto.subtle.decrypt
+                            #js {:name "AES-GCM"
+                                 :iv iv}
+                            key'
+                            ciphertext)]
+      (.decode decoder decrypted-data))))
 
 (comment
   (->
@@ -69,15 +71,13 @@
            range' (range 10 ;; 100000
                          )
            start (.getTime (js/Date.))
-           <encrypt-text (<gen-encrypt-text-fn salt "password")
-           _ (def <encrypt-text <encrypt-text)
-           encrypted-package-coll (p/all (map #(<encrypt-text "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq") range'))
+           key' (<salt+password->key salt "password")
+           encrypted-package-coll (p/all (map #(<encrypt-text key' "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq") range'))
            end (.getTime (js/Date.))]
      ;; (prn :encrypted-package-coll encrypted-package-coll)
      (println :encrypt-bench (count range') "in" (- end start) "ms")
      (p/let [start2 (.getTime (js/Date.))
-             <decrypt-text (<gen-decrypt-text-fn salt "password")
-             xx (p/all (map <decrypt-text encrypted-package-coll))
+             xx (p/all (map #(<decrypt-text key' %) encrypted-package-coll))
              end2 (.getTime (js/Date.))]
        ;; (prn :xx xx)
        (println :decrypt-bench (count range') "in" (- end2 start2) "ms")))

+ 2 - 0
src/main/frontend/worker/rtc/full_upload_download_graph.cljs

@@ -12,6 +12,7 @@
             [frontend.worker.rtc.client-op :as client-op]
             [frontend.worker.rtc.const :as rtc-const]
             [frontend.worker.rtc.db :as rtc-db]
+            [frontend.worker.rtc.encrypt :as rtc-encrypt]
             [frontend.worker.rtc.log-and-state :as rtc-log-and-state]
             [frontend.worker.rtc.ws-util :as ws-util]
             [frontend.worker.shared-service :as shared-service]
@@ -125,6 +126,7 @@
 (defn new-task--upload-graph
   [get-ws-create-task repo conn remote-graph-name major-schema-version]
   (m/sp
+    (ldb/transact! conn [(ldb/kv :logseq.kv/graph-rtc-encrypt-salt (rtc-encrypt/gen-salt))])
     (rtc-log-and-state/rtc-log :rtc.log/upload {:sub-type :fetching-presigned-put-url
                                                 :message "fetching presigned put-url"})
     (let [[{:keys [url key]} all-blocks-str]