Bladeren bron

Add functionality to download and decrypt files

Vishnu Mohandas 4 jaren geleden
bovenliggende
commit
a85ef0de9a
3 gewijzigde bestanden met toevoegingen van 36 en 3 verwijderingen
  1. 1 1
      src/services/fileService.ts
  2. 27 1
      src/utils/crypto/libsodium.ts
  3. 8 1
      src/worker/crypto.worker.js

+ 1 - 1
src/services/fileService.ts

@@ -134,7 +134,7 @@ export const getPreview = async (token: string, file: file) => {
         { token }, null, { responseType: 'arraybuffer' },
     );
     const worker = await new CryptoWorker();
-    const decrypted: any = await worker.decryptFile(
+    const decrypted: any = await worker.decryptThumbnail(
         new Uint8Array(resp.data),
         await worker.fromB64(file.thumbnail.decryptionHeader),
         file.key);

+ 27 - 1
src/utils/crypto/libsodium.ts

@@ -1,12 +1,38 @@
 import sodium from 'libsodium-wrappers';
 
-export async function decryptChaCha(data: Uint8Array, header: Uint8Array, key: Uint8Array) {
+const encryptionChunkSize = 4 * 1024 * 1024;
+
+export async function decryptChaChaOneShot(data: Uint8Array, header: Uint8Array, key: Uint8Array) {
     await sodium.ready;
     const pullState = sodium.crypto_secretstream_xchacha20poly1305_init_pull(header, key);
     const pullResult = sodium.crypto_secretstream_xchacha20poly1305_pull(pullState, data, null);
     return pullResult.message;
 }
 
+export async function decryptChaCha(data: Uint8Array, header: Uint8Array, key: Uint8Array) {
+    await sodium.ready;
+    const pullState = sodium.crypto_secretstream_xchacha20poly1305_init_pull(header, key);
+    const decryptionChunkSize =
+        encryptionChunkSize + sodium.crypto_secretstream_xchacha20poly1305_ABYTES;
+    var bytesRead = 0;
+    var decryptedData = [];
+    var tag = sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE;
+    while (tag != sodium.crypto_secretstream_xchacha20poly1305_TAG_FINAL) {
+        var chunkSize = decryptionChunkSize;
+        if (bytesRead + chunkSize > data.length) {
+            chunkSize = data.length - bytesRead;
+        }
+        const buffer = data.slice(bytesRead, bytesRead + chunkSize);
+        const pullResult = sodium.crypto_secretstream_xchacha20poly1305_pull(pullState, buffer);
+        for (var index = 0; index < pullResult.message.length; index++) {
+            decryptedData.push(pullResult.message[index]);
+        }
+        tag = pullResult.tag;
+        bytesRead += chunkSize;
+    }
+    return Uint8Array.from(decryptedData);
+}
+
 export async function encryptToB64(data: string, key: string) {
     await sodium.ready;
     var bKey: Uint8Array;

+ 8 - 1
src/worker/crypto.worker.js

@@ -3,13 +3,20 @@ import * as libsodium from 'utils/crypto/libsodium';
 
 export class Crypto {
     async decryptMetadata(file) {
-        const encodedMetadata = await libsodium.decryptChaCha(
+        const encodedMetadata = await libsodium.decryptChaChaOneShot(
             await libsodium.fromB64(file.metadata.encryptedData),
             await libsodium.fromB64(file.metadata.decryptionHeader),
             file.key);
         return JSON.parse(new TextDecoder().decode(encodedMetadata));
     }
 
+    async decryptThumbnail(fileData, header, key) {
+        return libsodium.decryptChaChaOneShot(
+            fileData,
+            header,
+            key);
+    }
+
     async decryptFile(fileData, header, key) {
         return libsodium.decryptChaCha(
             fileData,