creek

The AI Image Editor of 2030

lib/services/encryption_service.dart (2038B)


 1import 'dart:convert';
 2import 'dart:typed_data';
 3import 'package:cryptography/cryptography.dart';
 4import 'package:flutter_dotenv/flutter_dotenv.dart';
 5
 6class EncryptionService {
 7  final _algorithm = AesGcm.with256bits();
 8
 9  Future<SecretKey> _getSecretKey() async {
10    // 1. Fetch key from environment variables
11    final base64Key = dotenv.env['SHARED_SECRET_KEY'];
12
13    if (base64Key == null || base64Key.isEmpty) {
14      throw Exception("❌ SHARED_SECRET_KEY not found in .env file");
15    }
16
17    // 2. Decode the Base64 string to bytes
18    final keyBytes = base64Decode(base64Key);
19    return SecretKey(keyBytes);
20  }
21
22  Future<String> encrypt(String plainText) async {
23    final secretKey = await _getSecretKey();
24
25    // 1. Convert text to bytes
26    final messageBytes = utf8.encode(plainText);
27
28    // 2. Encrypt (Generates a random nonce automatically)
29    final secretBox = await _algorithm.encrypt(
30      messageBytes,
31      secretKey: secretKey,
32    );
33
34    // 3. Pack: Nonce + Ciphertext + Tag (MAC)
35    // Note: secretBox.mac.bytes is the Tag
36    final combined =
37        secretBox.nonce + secretBox.cipherText + secretBox.mac.bytes;
38
39    // 4. Return Base64
40    return base64Encode(combined);
41  }
42
43  Future<String?> decrypt(String encryptedBase64) async {
44    try {
45      final secretKey = await _getSecretKey();
46
47      // 1. Decode Base64
48      final data = base64Decode(encryptedBase64);
49
50      // 2. Unpack
51      // GCM Nonce is 12 bytes
52      final nonce = data.sublist(0, 12);
53      // Tag (MAC) is last 16 bytes
54      final tag = data.sublist(data.length - 16);
55      // Ciphertext
56      final ciphertext = data.sublist(12, data.length - 16);
57
58      // 3. Reconstruct SecretBox
59      final secretBox = SecretBox(ciphertext, nonce: nonce, mac: Mac(tag));
60
61      // 4. Decrypt
62      final decryptedBytes = await _algorithm.decrypt(
63        secretBox,
64        secretKey: secretKey,
65      );
66
67      return utf8.decode(decryptedBytes);
68    } catch (e) {
69      print("Decryption error: $e");
70      return null;
71    }
72  }
73}