Quellcode durchsuchen

Move to XChaCha for thumbnail and metadata encryption

Vishnu Mohandas vor 4 Jahren
Ursprung
Commit
27f019af57

+ 31 - 30
lib/db/files_db.dart

@@ -1,7 +1,6 @@
 import 'dart:io';
 import 'dart:io';
 
 
 import 'package:logging/logging.dart';
 import 'package:logging/logging.dart';
-import 'package:photos/models/decryption_params.dart';
 import 'package:photos/models/file_type.dart';
 import 'package:photos/models/file_type.dart';
 import 'package:photos/models/location.dart';
 import 'package:photos/models/location.dart';
 import 'package:photos/models/file.dart';
 import 'package:photos/models/file.dart';
@@ -32,9 +31,11 @@ class FilesDB {
   static final columnCreationTime = 'creation_time';
   static final columnCreationTime = 'creation_time';
   static final columnModificationTime = 'modification_time';
   static final columnModificationTime = 'modification_time';
   static final columnUpdationTime = 'updation_time';
   static final columnUpdationTime = 'updation_time';
-  static final columnFileDecryptionParams = 'file_decryption_params';
-  static final columnThumbnailDecryptionParams = 'thumbnail_decryption_params';
-  static final columnMetadataDecryptionParams = 'metadata_decryption_params';
+  static final columnEncryptedKey = 'encrypted_key';
+  static final columnKeyDecryptionNonce = 'key_decryption_nonce';
+  static final columnFileDecryptionHeader = 'file_decryption_header';
+  static final columnThumbnailDecryptionHeader = 'thumbnail_decryption_header';
+  static final columnMetadataDecryptionHeader = 'metadata_decryption_header';
 
 
   // make this a singleton class
   // make this a singleton class
   FilesDB._privateConstructor();
   FilesDB._privateConstructor();
@@ -76,9 +77,12 @@ class FilesDB {
             $columnCreationTime TEXT NOT NULL,
             $columnCreationTime TEXT NOT NULL,
             $columnModificationTime TEXT NOT NULL,
             $columnModificationTime TEXT NOT NULL,
             $columnUpdationTime TEXT,
             $columnUpdationTime TEXT,
-            $columnFileDecryptionParams TEXT,
-            $columnThumbnailDecryptionParams TEXT,
-            $columnMetadataDecryptionParams TEXT
+            $columnEncryptedKey TEXT,
+            $columnKeyDecryptionNonce TEXT,
+            $columnUpdationTime TEXT,
+            $columnFileDecryptionHeader TEXT,
+            $columnThumbnailDecryptionHeader TEXT,
+            $columnMetadataDecryptionHeader TEXT
           )
           )
           ''');
           ''');
   }
   }
@@ -227,18 +231,21 @@ class FilesDB {
     int generatedID,
     int generatedID,
     int uploadedID,
     int uploadedID,
     int updationTime,
     int updationTime,
-    DecryptionParams fileDecryptionParams,
-    DecryptionParams thumbnailDecryptionParams,
-    DecryptionParams metadataDecryptionParams,
+    String encryptedKey,
+    String keyDecryptionNonce,
+    String fileDecryptionHeader,
+    String thumbnailDecryptionHeader,
+    String metadataDecryptionHeader,
   ) async {
   ) async {
     final db = await instance.database;
     final db = await instance.database;
     final values = new Map<String, dynamic>();
     final values = new Map<String, dynamic>();
     values[columnUploadedFileID] = uploadedID;
     values[columnUploadedFileID] = uploadedID;
     values[columnUpdationTime] = updationTime;
     values[columnUpdationTime] = updationTime;
-    values[columnFileDecryptionParams] = fileDecryptionParams.toJson();
-    values[columnThumbnailDecryptionParams] =
-        thumbnailDecryptionParams.toJson();
-    values[columnMetadataDecryptionParams] = metadataDecryptionParams.toJson();
+    values[columnEncryptedKey] = encryptedKey;
+    values[columnKeyDecryptionNonce] = keyDecryptionNonce;
+    values[columnFileDecryptionHeader] = fileDecryptionHeader;
+    values[columnThumbnailDecryptionHeader] = thumbnailDecryptionHeader;
+    values[columnMetadataDecryptionHeader] = metadataDecryptionHeader;
     return await db.update(
     return await db.update(
       table,
       table,
       values,
       values,
@@ -390,16 +397,11 @@ class FilesDB {
     row[columnCreationTime] = file.creationTime;
     row[columnCreationTime] = file.creationTime;
     row[columnModificationTime] = file.modificationTime;
     row[columnModificationTime] = file.modificationTime;
     row[columnUpdationTime] = file.updationTime;
     row[columnUpdationTime] = file.updationTime;
-    row[columnFileDecryptionParams] = file.fileDecryptionParams == null
-        ? null
-        : file.fileDecryptionParams.toJson();
-    row[columnThumbnailDecryptionParams] =
-        file.thumbnailDecryptionParams == null
-            ? null
-            : file.thumbnailDecryptionParams.toJson();
-    row[columnMetadataDecryptionParams] = file.metadataDecryptionParams == null
-        ? null
-        : file.metadataDecryptionParams.toJson();
+    row[columnEncryptedKey] = file.encryptedKey;
+    row[columnKeyDecryptionNonce] = file.keyDecryptionNonce;
+    row[columnFileDecryptionHeader] = file.fileDecryptionHeader;
+    row[columnThumbnailDecryptionHeader] = file.thumbnailDecryptionHeader;
+    row[columnMetadataDecryptionHeader] = file.metadataDecryptionHeader;
     return row;
     return row;
   }
   }
 
 
@@ -422,12 +424,11 @@ class FilesDB {
     file.updationTime = row[columnUpdationTime] == null
     file.updationTime = row[columnUpdationTime] == null
         ? -1
         ? -1
         : int.parse(row[columnUpdationTime]);
         : int.parse(row[columnUpdationTime]);
-    file.fileDecryptionParams =
-        DecryptionParams.fromJson(row[columnFileDecryptionParams]);
-    file.thumbnailDecryptionParams =
-        DecryptionParams.fromJson(row[columnThumbnailDecryptionParams]);
-    file.metadataDecryptionParams =
-        DecryptionParams.fromJson(row[columnMetadataDecryptionParams]);
+    file.encryptedKey = row[columnEncryptedKey];
+    file.keyDecryptionNonce = row[columnKeyDecryptionNonce];
+    file.fileDecryptionHeader = row[columnFileDecryptionHeader];
+    file.thumbnailDecryptionHeader = row[columnThumbnailDecryptionHeader];
+    file.metadataDecryptionHeader = row[columnMetadataDecryptionHeader];
     return file;
     return file;
   }
   }
 }
 }

+ 8 - 0
lib/models/chacha_encryption_result.dart

@@ -0,0 +1,8 @@
+import 'dart:typed_data';
+
+class ChaChaEncryptionResult {
+  final Uint8List encryptedData;
+  final Uint8List header;
+
+  ChaChaEncryptionResult(this.encryptedData, this.header);
+}

+ 0 - 82
lib/models/decryption_params.dart

@@ -1,82 +0,0 @@
-import 'dart:convert';
-
-class DecryptionParams {
-  final String encryptedKey;
-  final String keyDecryptionNonce;
-  String header;
-  String nonce;
-
-  DecryptionParams({
-    this.encryptedKey,
-    this.keyDecryptionNonce,
-    this.header,
-    this.nonce,
-  });
-
-  DecryptionParams copyWith({
-    String encryptedKey,
-    String keyDecryptionNonce,
-    String header,
-    String nonce,
-  }) {
-    return DecryptionParams(
-      encryptedKey: encryptedKey ?? this.encryptedKey,
-      keyDecryptionNonce: keyDecryptionNonce ?? this.keyDecryptionNonce,
-      header: header ?? this.header,
-      nonce: nonce ?? this.nonce,
-    );
-  }
-
-  Map<String, dynamic> toMap() {
-    return {
-      'encryptedKey': encryptedKey,
-      'keyDecryptionNonce': keyDecryptionNonce,
-      'header': header,
-      'nonce': nonce,
-    };
-  }
-
-  factory DecryptionParams.fromMap(Map<String, dynamic> map) {
-    if (map == null) return null;
-
-    return DecryptionParams(
-      encryptedKey: map['encryptedKey'],
-      keyDecryptionNonce: map['keyDecryptionNonce'],
-      header: map['header'],
-      nonce: map['nonce'],
-    );
-  }
-
-  String toJson() => json.encode(toMap());
-
-  factory DecryptionParams.fromJson(String source) {
-    if (source == null) {
-      return null;
-    }
-    return DecryptionParams.fromMap(json.decode(source));
-  }
-
-  @override
-  String toString() {
-    return 'DecryptionParams(encryptedKey: $encryptedKey, keyDecryptionNonce: $keyDecryptionNonce, header: $header, nonce: $nonce)';
-  }
-
-  @override
-  bool operator ==(Object o) {
-    if (identical(this, o)) return true;
-
-    return o is DecryptionParams &&
-        o.encryptedKey == encryptedKey &&
-        o.keyDecryptionNonce == keyDecryptionNonce &&
-        o.header == header &&
-        o.nonce == nonce;
-  }
-
-  @override
-  int get hashCode {
-    return encryptedKey.hashCode ^
-        keyDecryptionNonce.hashCode ^
-        header.hashCode ^
-        nonce.hashCode;
-  }
-}

+ 6 - 8
lib/models/file.dart

@@ -1,7 +1,6 @@
 import 'package:photo_manager/photo_manager.dart';
 import 'package:photo_manager/photo_manager.dart';
 import 'package:path/path.dart';
 import 'package:path/path.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/configuration.dart';
-import 'package:photos/models/decryption_params.dart';
 import 'package:photos/models/file_type.dart';
 import 'package:photos/models/file_type.dart';
 import 'package:photos/models/location.dart';
 import 'package:photos/models/location.dart';
 
 
@@ -19,9 +18,11 @@ class File {
   int updationTime;
   int updationTime;
   Location location;
   Location location;
   FileType fileType;
   FileType fileType;
-  DecryptionParams fileDecryptionParams;
-  DecryptionParams thumbnailDecryptionParams;
-  DecryptionParams metadataDecryptionParams;
+  String encryptedKey;
+  String keyDecryptionNonce;
+  String fileDecryptionHeader;
+  String thumbnailDecryptionHeader;
+  String metadataDecryptionHeader;
 
 
   File();
   File();
 
 
@@ -137,10 +138,7 @@ class File {
   @override
   @override
   String toString() {
   String toString() {
     return '''File(generatedId: $generatedID, uploadedFileId: $uploadedFileID, 
     return '''File(generatedId: $generatedID, uploadedFileId: $uploadedFileID, 
-      localId: $localID, title: $title, deviceFolder: $deviceFolder, 
-      fileDecryptionParams: $fileDecryptionParams, 
-      thumbnailDecryptionParams: $thumbnailDecryptionParams,
-      metadataDecryptionParams: $metadataDecryptionParams,
+      localId: $localID, title: $title, deviceFolder: $deviceFolder,
       location: $location, fileType: $fileType, creationTime: $creationTime, 
       location: $location, fileType: $fileType, creationTime: $creationTime, 
       modificationTime: $modificationTime, updationTime: $updationTime)''';
       modificationTime: $modificationTime, updationTime: $updationTime)''';
   }
   }

+ 5 - 0
lib/services/collections_service.dart

@@ -0,0 +1,5 @@
+import 'package:logging/logging.dart';
+
+class CollectionsService {
+  final _logger = Logger("CollectionsService");
+}

+ 5 - 3
lib/services/folder_service.dart

@@ -74,9 +74,11 @@ class FolderSharingService {
           existingPhoto.generatedID,
           existingPhoto.generatedID,
           file.uploadedFileID,
           file.uploadedFileID,
           file.updationTime,
           file.updationTime,
-          file.fileDecryptionParams,
-          file.thumbnailDecryptionParams,
-          file.metadataDecryptionParams,
+          file.encryptedKey,
+          file.keyDecryptionNonce,
+          file.fileDecryptionHeader,
+          file.thumbnailDecryptionHeader,
+          file.metadataDecryptionHeader,
         );
         );
       } catch (e) {
       } catch (e) {
         await FilesDB.instance.insert(file);
         await FilesDB.instance.insert(file);

+ 13 - 13
lib/services/sync_service.dart

@@ -229,9 +229,11 @@ class SyncService {
           file.generatedID,
           file.generatedID,
           uploadedFile.uploadedFileID,
           uploadedFile.uploadedFileID,
           uploadedFile.updationTime,
           uploadedFile.updationTime,
-          file.fileDecryptionParams,
-          file.thumbnailDecryptionParams,
-          file.metadataDecryptionParams,
+          file.encryptedKey,
+          file.keyDecryptionNonce,
+          file.fileDecryptionHeader,
+          file.thumbnailDecryptionHeader,
+          file.metadataDecryptionHeader,
         );
         );
         Bus.instance.fire(PhotoUploadEvent(
         Bus.instance.fire(PhotoUploadEvent(
             completed: i + 1, total: filesToBeUploaded.length));
             completed: i + 1, total: filesToBeUploaded.length));
@@ -245,20 +247,18 @@ class SyncService {
   Future _storeDiff(List<File> diff, String prefKey) async {
   Future _storeDiff(List<File> diff, String prefKey) async {
     for (File file in diff) {
     for (File file in diff) {
       try {
       try {
-        final existingPhoto = await _db.getMatchingFile(
-            file.localID,
-            file.title,
-            file.deviceFolder,
-            file.creationTime,
-            file.modificationTime,
+        final existingFile = await _db.getMatchingFile(file.localID, file.title,
+            file.deviceFolder, file.creationTime, file.modificationTime,
             alternateTitle: getHEICFileNameForJPG(file));
             alternateTitle: getHEICFileNameForJPG(file));
         await _db.update(
         await _db.update(
-          existingPhoto.generatedID,
+          existingFile.generatedID,
           file.uploadedFileID,
           file.uploadedFileID,
           file.updationTime,
           file.updationTime,
-          file.fileDecryptionParams,
-          file.thumbnailDecryptionParams,
-          file.metadataDecryptionParams,
+          file.encryptedKey,
+          file.keyDecryptionNonce,
+          file.fileDecryptionHeader,
+          file.thumbnailDecryptionHeader,
+          file.metadataDecryptionHeader,
         );
         );
       } catch (e) {
       } catch (e) {
         file.localID = null; // File uploaded from a different device
         file.localID = null; // File uploaded from a different device

+ 24 - 5
lib/utils/crypto_util.dart

@@ -5,6 +5,7 @@ import 'dart:io' as io;
 import 'package:computer/computer.dart';
 import 'package:computer/computer.dart';
 import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:logging/logging.dart';
 import 'package:logging/logging.dart';
+import 'package:photos/models/chacha_encryption_result.dart';
 
 
 import 'package:photos/models/encrypted_data_attributes.dart';
 import 'package:photos/models/encrypted_data_attributes.dart';
 import 'package:photos/models/encrypted_file_attributes.dart';
 import 'package:photos/models/encrypted_file_attributes.dart';
@@ -32,7 +33,7 @@ bool cryptoPwhashStrVerify(Map<String, dynamic> args) {
   return Sodium.cryptoPwhashStrVerify(args["hash"], args["input"]) == 0;
   return Sodium.cryptoPwhashStrVerify(args["hash"], args["input"]) == 0;
 }
 }
 
 
-ChaChaAttributes chachaEncrypt(Map<String, dynamic> args) {
+ChaChaAttributes chachaEncryptFile(Map<String, dynamic> args) {
   final encryptionStartTime = DateTime.now().millisecondsSinceEpoch;
   final encryptionStartTime = DateTime.now().millisecondsSinceEpoch;
   final logger = Logger("ChaChaEncrypt");
   final logger = Logger("ChaChaEncrypt");
   final sourceFile = io.File(args["sourceFilePath"]);
   final sourceFile = io.File(args["sourceFilePath"]);
@@ -111,15 +112,33 @@ class CryptoUtil {
     args["source"] = source;
     args["source"] = source;
     args["nonce"] = nonce;
     args["nonce"] = nonce;
     args["key"] = key;
     args["key"] = key;
-    final encryptedData =
-        await Computer().compute(cryptoSecretboxEasy, param: args);
-
+    final encryptedData = cryptoSecretboxEasy(args);
     return EncryptedData(
     return EncryptedData(
         EncryptionAttribute(bytes: key),
         EncryptionAttribute(bytes: key),
         EncryptionAttribute(bytes: nonce),
         EncryptionAttribute(bytes: nonce),
         EncryptionAttribute(bytes: encryptedData));
         EncryptionAttribute(bytes: encryptedData));
   }
   }
 
 
+  static ChaChaEncryptionResult encryptStream(Uint8List source, Uint8List key) {
+    final initPushResult =
+        Sodium.cryptoSecretstreamXchacha20poly1305InitPush(key);
+    final encryptedData = Sodium.cryptoSecretstreamXchacha20poly1305Push(
+        initPushResult.state,
+        source,
+        null,
+        Sodium.cryptoSecretstreamXchacha20poly1305TagFinal);
+    return ChaChaEncryptionResult(encryptedData, initPushResult.header);
+  }
+
+  static Uint8List decryptStream(
+      Uint8List source, Uint8List key, Uint8List header) {
+    final pullState =
+        Sodium.cryptoSecretstreamXchacha20poly1305InitPull(header, key);
+    final pullResult =
+        Sodium.cryptoSecretstreamXchacha20poly1305Pull(pullState, source, null);
+    return pullResult.m;
+  }
+
   static Future<Uint8List> decrypt(
   static Future<Uint8List> decrypt(
       Uint8List cipher, Uint8List key, Uint8List nonce,
       Uint8List cipher, Uint8List key, Uint8List nonce,
       {bool background = false}) async {
       {bool background = false}) async {
@@ -141,7 +160,7 @@ class CryptoUtil {
     final args = Map<String, dynamic>();
     final args = Map<String, dynamic>();
     args["sourceFilePath"] = sourceFilePath;
     args["sourceFilePath"] = sourceFilePath;
     args["destinationFilePath"] = destinationFilePath;
     args["destinationFilePath"] = destinationFilePath;
-    return Computer().compute(chachaEncrypt, param: args);
+    return Computer().compute(chachaEncryptFile, param: args);
   }
   }
 
 
   static Future<void> decryptFile(
   static Future<void> decryptFile(

+ 10 - 15
lib/utils/file_downloader.dart

@@ -6,9 +6,9 @@ import 'package:logging/logging.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/events/remote_sync_event.dart';
 import 'package:photos/events/remote_sync_event.dart';
-import 'package:photos/models/decryption_params.dart';
 import 'package:photos/models/file.dart';
 import 'package:photos/models/file.dart';
 import 'package:photos/utils/crypto_util.dart';
 import 'package:photos/utils/crypto_util.dart';
+import 'package:photos/utils/file_util.dart';
 
 
 class DiffFetcher {
 class DiffFetcher {
   final _logger = Logger("FileDownloader");
   final _logger = Logger("FileDownloader");
@@ -36,21 +36,16 @@ class DiffFetcher {
               file.ownerID = item["ownerID"];
               file.ownerID = item["ownerID"];
               file.updationTime = item["updationTime"];
               file.updationTime = item["updationTime"];
               file.isEncrypted = true;
               file.isEncrypted = true;
-              file.fileDecryptionParams =
-                  DecryptionParams.fromMap(item["file"]["decryptionParams"]);
-              file.thumbnailDecryptionParams = DecryptionParams.fromMap(
-                  item["thumbnail"]["decryptionParams"]);
-              file.metadataDecryptionParams = DecryptionParams.fromMap(
-                  item["metadata"]["decryptionParams"]);
-              final metadataDecryptionKey = await CryptoUtil.decrypt(
-                  Sodium.base642bin(file.metadataDecryptionParams.encryptedKey),
-                  Configuration.instance.getKey(),
-                  Sodium.base642bin(
-                      file.metadataDecryptionParams.keyDecryptionNonce));
-              final encodedMetadata = await CryptoUtil.decrypt(
+              file.encryptedKey = item["encryptedKey"];
+              file.keyDecryptionNonce = item["keyDecryptionNonce"];
+              file.fileDecryptionHeader = item["fileDecryptionHeader"];
+              file.thumbnailDecryptionHeader =
+                  item["thumbnailDecryptionHeader"];
+              file.metadataDecryptionHeader = item["metadataDecryptionHeader"];
+              final encodedMetadata = CryptoUtil.decryptStream(
                 Sodium.base642bin(item["metadata"]["encryptedData"]),
                 Sodium.base642bin(item["metadata"]["encryptedData"]),
-                metadataDecryptionKey,
-                Sodium.base642bin(file.metadataDecryptionParams.nonce),
+                await decryptFileKey(file),
+                Sodium.base642bin(file.metadataDecryptionHeader),
               );
               );
               Map<String, dynamic> metadata =
               Map<String, dynamic> metadata =
                   jsonDecode(utf8.decode(encodedMetadata));
                   jsonDecode(utf8.decode(encodedMetadata));

+ 22 - 38
lib/utils/file_uploader.dart

@@ -1,10 +1,10 @@
 import 'dart:convert';
 import 'dart:convert';
 import 'dart:io' as io;
 import 'dart:io' as io;
 import 'package:dio/dio.dart';
 import 'package:dio/dio.dart';
+import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:logging/logging.dart';
 import 'package:logging/logging.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/constants.dart';
 import 'package:photos/core/constants.dart';
-import 'package:photos/models/decryption_params.dart';
 import 'package:photos/models/file.dart';
 import 'package:photos/models/file.dart';
 import 'package:photos/models/upload_url.dart';
 import 'package:photos/models/upload_url.dart';
 import 'package:photos/utils/crypto_util.dart';
 import 'package:photos/utils/crypto_util.dart';
@@ -56,16 +56,6 @@ class FileUploader {
     final fileUploadURL = await getUploadURL();
     final fileUploadURL = await getUploadURL();
     String fileObjectKey = await putFile(fileUploadURL, encryptedFile);
     String fileObjectKey = await putFile(fileUploadURL, encryptedFile);
 
 
-    final encryptedFileKey = await CryptoUtil.encrypt(
-      fileAttributes.key.bytes,
-      key: Configuration.instance.getKey(),
-    );
-    final fileDecryptionParams = DecryptionParams(
-      encryptedKey: encryptedFileKey.encryptedData.base64,
-      keyDecryptionNonce: encryptedFileKey.nonce.base64,
-      header: fileAttributes.header.base64,
-    );
-
     final thumbnailData = (await (await file.getAsset()).thumbDataWithSize(
     final thumbnailData = (await (await file.getAsset()).thumbDataWithSize(
       THUMBNAIL_LARGE_SIZE,
       THUMBNAIL_LARGE_SIZE,
       THUMBNAIL_LARGE_SIZE,
       THUMBNAIL_LARGE_SIZE,
@@ -74,47 +64,37 @@ class FileUploader {
     final encryptedThumbnailName =
     final encryptedThumbnailName =
         file.generatedID.toString() + "_thumbnail.encrypted";
         file.generatedID.toString() + "_thumbnail.encrypted";
     final encryptedThumbnailPath = tempDirectory + encryptedThumbnailName;
     final encryptedThumbnailPath = tempDirectory + encryptedThumbnailName;
-    final encryptedThumbnail = await CryptoUtil.encrypt(thumbnailData);
+    final encryptedThumbnail =
+        CryptoUtil.encryptStream(thumbnailData, fileAttributes.key.bytes);
     io.File(encryptedThumbnailPath)
     io.File(encryptedThumbnailPath)
-        .writeAsBytesSync(encryptedThumbnail.encryptedData.bytes);
+        .writeAsBytesSync(encryptedThumbnail.encryptedData);
 
 
     final thumbnailUploadURL = await getUploadURL();
     final thumbnailUploadURL = await getUploadURL();
     String thumbnailObjectKey =
     String thumbnailObjectKey =
         await putFile(thumbnailUploadURL, io.File(encryptedThumbnailPath));
         await putFile(thumbnailUploadURL, io.File(encryptedThumbnailPath));
 
 
-    final encryptedThumbnailKey = await CryptoUtil.encrypt(
-      encryptedThumbnail.key.bytes,
-      key: Configuration.instance.getKey(),
-    );
-    final thumbnailDecryptionParams = DecryptionParams(
-      encryptedKey: encryptedThumbnailKey.encryptedData.base64,
-      keyDecryptionNonce: encryptedThumbnailKey.nonce.base64,
-      nonce: encryptedThumbnail.nonce.base64,
-    );
+    final encryptedMetadata = CryptoUtil.encryptStream(
+        utf8.encode(jsonEncode(file.getMetadata())), fileAttributes.key.bytes);
 
 
-    final metadata = jsonEncode(file.getMetadata());
-    final encryptedMetadata = await CryptoUtil.encrypt(utf8.encode(metadata));
-    final encryptedMetadataKey = await CryptoUtil.encrypt(
-      encryptedMetadata.key.bytes,
+    final encryptedFileKey = await CryptoUtil.encrypt(
+      fileAttributes.key.bytes,
       key: Configuration.instance.getKey(),
       key: Configuration.instance.getKey(),
     );
     );
-    final metadataDecryptionParams = DecryptionParams(
-      encryptedKey: encryptedMetadataKey.encryptedData.base64,
-      keyDecryptionNonce: encryptedMetadataKey.nonce.base64,
-      nonce: encryptedMetadata.nonce.base64,
-    );
+
     final data = {
     final data = {
+      "encryptedKey": encryptedFileKey.encryptedData.base64,
+      "keyDecryptionNonce": encryptedFileKey.nonce.base64,
       "file": {
       "file": {
         "objectKey": fileObjectKey,
         "objectKey": fileObjectKey,
-        "decryptionParams": fileDecryptionParams.toMap(),
+        "header": fileAttributes.header.base64,
       },
       },
       "thumbnail": {
       "thumbnail": {
         "objectKey": thumbnailObjectKey,
         "objectKey": thumbnailObjectKey,
-        "decryptionParams": thumbnailDecryptionParams.toMap(),
+        "header": Sodium.bin2base64(encryptedThumbnail.header),
       },
       },
       "metadata": {
       "metadata": {
-        "encryptedData": encryptedMetadata.encryptedData.base64,
-        "decryptionParams": metadataDecryptionParams.toMap(),
+        "encryptedData": Sodium.bin2base64(encryptedMetadata.encryptedData),
+        "header": Sodium.bin2base64(encryptedMetadata.header),
       }
       }
     };
     };
     return _dio
     return _dio
@@ -131,9 +111,13 @@ class FileUploader {
       file.uploadedFileID = data["id"];
       file.uploadedFileID = data["id"];
       file.updationTime = data["updationTime"];
       file.updationTime = data["updationTime"];
       file.ownerID = data["ownerID"];
       file.ownerID = data["ownerID"];
-      file.fileDecryptionParams = fileDecryptionParams;
-      file.thumbnailDecryptionParams = thumbnailDecryptionParams;
-      file.metadataDecryptionParams = metadataDecryptionParams;
+      file.encryptedKey = encryptedFileKey.encryptedData.base64;
+      file.keyDecryptionNonce = encryptedFileKey.nonce.base64;
+      file.fileDecryptionHeader = fileAttributes.header.base64;
+      file.thumbnailDecryptionHeader =
+          Sodium.bin2base64(encryptedThumbnail.header);
+      file.metadataDecryptionHeader =
+          Sodium.bin2base64(encryptedMetadata.header);
       return file;
       return file;
     });
     });
   }
   }

+ 13 - 12
lib/utils/file_util.dart

@@ -178,12 +178,9 @@ Future<io.File> _downloadAndDecrypt(File file, BaseCacheManager cacheManager,
     logger.info("File downloaded: " + file.uploadedFileID.toString());
     logger.info("File downloaded: " + file.uploadedFileID.toString());
     var attributes = ChaChaAttributes(
     var attributes = ChaChaAttributes(
       EncryptionAttribute(
       EncryptionAttribute(
-          bytes: await CryptoUtil.decrypt(
-        Sodium.base642bin(file.fileDecryptionParams.encryptedKey),
-        Configuration.instance.getKey(),
-        Sodium.base642bin(file.fileDecryptionParams.keyDecryptionNonce),
-      )),
-      EncryptionAttribute(base64: file.fileDecryptionParams.header),
+        bytes: await decryptFileKey(file),
+      ),
+      EncryptionAttribute(base64: file.fileDecryptionHeader),
     );
     );
     await CryptoUtil.decryptFile(
     await CryptoUtil.decryptFile(
         encryptedFilePath, decryptedFilePath, attributes);
         encryptedFilePath, decryptedFilePath, attributes);
@@ -209,14 +206,11 @@ Future<io.File> _downloadAndDecryptThumbnail(File file) async {
       "_thumbnail.decrypted";
       "_thumbnail.decrypted";
   return Dio().download(file.getThumbnailUrl(), temporaryPath).then((_) async {
   return Dio().download(file.getThumbnailUrl(), temporaryPath).then((_) async {
     final encryptedFile = io.File(temporaryPath);
     final encryptedFile = io.File(temporaryPath);
-    final thumbnailDecryptionKey = await CryptoUtil.decrypt(
-        Sodium.base642bin(file.thumbnailDecryptionParams.encryptedKey),
-        Configuration.instance.getKey(),
-        Sodium.base642bin(file.thumbnailDecryptionParams.keyDecryptionNonce));
-    final data = await CryptoUtil.decrypt(
+    final thumbnailDecryptionKey = await decryptFileKey(file);
+    final data = CryptoUtil.decryptStream(
       encryptedFile.readAsBytesSync(),
       encryptedFile.readAsBytesSync(),
       thumbnailDecryptionKey,
       thumbnailDecryptionKey,
-      Sodium.base642bin(file.thumbnailDecryptionParams.nonce),
+      Sodium.base642bin(file.thumbnailDecryptionHeader),
     );
     );
     encryptedFile.deleteSync();
     encryptedFile.deleteSync();
     return ThumbnailCacheManager().putFile(
     return ThumbnailCacheManager().putFile(
@@ -227,3 +221,10 @@ Future<io.File> _downloadAndDecryptThumbnail(File file) async {
     );
     );
   });
   });
 }
 }
+
+Future<Uint8List> decryptFileKey(File file) {
+  return CryptoUtil.decrypt(
+      Sodium.base642bin(file.encryptedKey),
+      Configuration.instance.getKey(),
+      Sodium.base642bin(file.keyDecryptionNonce));
+}