Line data Source code
1 : import 'package:flutter/foundation.dart';
2 : import '../worker.dart';
3 :
4 : /// Hash algorithms supported by CryptoWorker.
5 : ///
6 : /// **⚠️ Security Notice:**
7 : /// `md5` and `sha1` are cryptographically broken and should not be used for
8 : /// security-sensitive purposes (e.g., password hashing, integrity verification).
9 : /// Use [sha256] or [sha512] instead.
10 : enum HashAlgorithm {
11 : /// **Deprecated for security use.** MD5 is cryptographically broken.
12 : /// Use [sha256] or [sha512] for integrity checks.
13 : @Deprecated('MD5 is cryptographically broken. Use sha256 or sha512 instead.')
14 : md5('MD5'),
15 :
16 : /// **Deprecated for security use.** SHA-1 is cryptographically broken.
17 : /// Use [sha256] or [sha512] for integrity checks.
18 : @Deprecated(
19 : 'SHA-1 is cryptographically broken. Use sha256 or sha512 instead.')
20 : sha1('SHA-1'),
21 :
22 : sha256('SHA-256'),
23 : sha512('SHA-512');
24 :
25 : const HashAlgorithm(this.value);
26 : final String value;
27 : }
28 :
29 : /// Encryption algorithms supported by CryptoWorker.
30 : enum EncryptionAlgorithm {
31 : aes('AES');
32 :
33 : const EncryptionAlgorithm(this.value);
34 : final String value;
35 : }
36 :
37 : /// Crypto worker configuration for file hashing.
38 : ///
39 : /// Computes cryptographic hash of a file or string.
40 : @immutable
41 : final class CryptoHashWorker extends Worker {
42 2 : const CryptoHashWorker.file({
43 : required this.filePath,
44 : this.algorithm = HashAlgorithm.sha256,
45 : }) : data = null;
46 :
47 2 : const CryptoHashWorker.string({
48 : required this.data,
49 : this.algorithm = HashAlgorithm.sha256,
50 : }) : filePath = null;
51 :
52 : /// Path to file to hash (null if hashing string data).
53 : final String? filePath;
54 :
55 : /// String data to hash (null if hashing file).
56 : final String? data;
57 :
58 : /// Hash algorithm to use.
59 : final HashAlgorithm algorithm;
60 :
61 3 : @override
62 : String get workerClassName => 'CryptoWorker';
63 :
64 3 : @override
65 3 : Map<String, dynamic> toMap() => {
66 3 : 'workerType': 'crypto',
67 3 : 'operation': 'hash',
68 9 : if (filePath != null) 'filePath': filePath,
69 7 : if (data != null) 'data': data,
70 9 : 'algorithm': algorithm.value,
71 : };
72 : }
73 :
74 : /// Crypto worker configuration for file encryption.
75 : ///
76 : /// Encrypts a file using AES-256-GCM (authenticated encryption) with a
77 : /// PBKDF2-derived key (100,000 iterations, HMAC-SHA256).
78 : ///
79 : /// File format: `SALT(16) || NONCE(12) || CIPHERTEXT || GCM_TAG(16)`
80 : ///
81 : /// Both Android and iOS use AES-256-GCM with the same on-disk format, so
82 : /// files encrypted on one platform can be decrypted on the other.
83 : @immutable
84 : final class CryptoEncryptWorker extends Worker {
85 5 : const CryptoEncryptWorker({
86 : required this.inputPath,
87 : required this.outputPath,
88 : required this.password,
89 : this.algorithm = EncryptionAlgorithm.aes,
90 : });
91 :
92 : /// Path to file to encrypt.
93 : final String inputPath;
94 :
95 : /// Path where encrypted file will be saved.
96 : final String outputPath;
97 :
98 : /// Password for encryption (will be used to derive key).
99 : final String password;
100 :
101 : /// Encryption algorithm (currently only AES supported).
102 : final EncryptionAlgorithm algorithm;
103 :
104 2 : @override
105 : String get workerClassName => 'CryptoWorker';
106 :
107 3 : @override
108 3 : Map<String, dynamic> toMap() => {
109 : 'workerType': 'crypto',
110 : 'operation': 'encrypt',
111 3 : 'filePath': inputPath,
112 3 : 'outputPath': outputPath,
113 3 : 'password': password,
114 6 : 'algorithm': algorithm.value,
115 : };
116 : }
117 :
118 : /// Crypto worker configuration for file decryption.
119 : ///
120 : /// Decrypts a file previously encrypted by [CryptoEncryptWorker].
121 : /// Both Android and iOS use AES-256-GCM with the same on-disk format, so
122 : /// cross-platform decryption is fully supported.
123 : @immutable
124 : final class CryptoDecryptWorker extends Worker {
125 4 : const CryptoDecryptWorker({
126 : required this.inputPath,
127 : required this.outputPath,
128 : required this.password,
129 : this.algorithm = EncryptionAlgorithm.aes,
130 : });
131 :
132 : /// Path to encrypted file.
133 : final String inputPath;
134 :
135 : /// Path where decrypted file will be saved.
136 : final String outputPath;
137 :
138 : /// Password used for encryption.
139 : final String password;
140 :
141 : /// Encryption algorithm used (currently only AES supported).
142 : final EncryptionAlgorithm algorithm;
143 :
144 2 : @override
145 : String get workerClassName => 'CryptoWorker';
146 :
147 3 : @override
148 3 : Map<String, dynamic> toMap() => {
149 : 'workerType': 'crypto',
150 : 'operation': 'decrypt',
151 3 : 'filePath': inputPath,
152 3 : 'outputPath': outputPath,
153 3 : 'password': password,
154 6 : 'algorithm': algorithm.value,
155 : };
156 : }
|