Update: 2026-06-16 01:17:28
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:math';
|
||||
import 'package:siro_rider/env/env.dart';
|
||||
import 'package:encrypt/encrypt.dart' as encrypt;
|
||||
import 'package:flutter/foundation.dart';
|
||||
@@ -10,6 +12,7 @@ class EncryptionHelper {
|
||||
|
||||
late final encrypt.Key key;
|
||||
late final encrypt.IV iv;
|
||||
static const String _gcmPrefix = 'GCM:';
|
||||
|
||||
EncryptionHelper._(this.key, this.iv);
|
||||
static EncryptionHelper get instance {
|
||||
@@ -39,31 +42,76 @@ class EncryptionHelper {
|
||||
debugPrint("EncryptionHelper initialized successfully.");
|
||||
}
|
||||
|
||||
/// Encrypts a string
|
||||
/// ✅ FIX H-04: Encrypts a string using AES-256-GCM (new) with random IV
|
||||
String encryptData(String plainText) {
|
||||
try {
|
||||
final encrypter =
|
||||
encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc));
|
||||
final encrypted = encrypter.encrypt(plainText, iv: iv);
|
||||
return encrypted.base64;
|
||||
// Try GCM first (secure mode with random IV)
|
||||
final randomIv = _generateRandomIv(12);
|
||||
// GCM mode in encrypt package handles nonce/IV length automatically (12 bytes recommended)
|
||||
final gcmEncrypter =
|
||||
encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.gcm));
|
||||
final encrypted = gcmEncrypter.encrypt(plainText, iv: randomIv);
|
||||
// Prefix with GCM: to distinguish from legacy CBC
|
||||
return '$_gcmPrefix${randomIv.base64}:${encrypted.base64}';
|
||||
} catch (e) {
|
||||
debugPrint('Encryption Error: $e');
|
||||
return '';
|
||||
debugPrint('GCM Encryption failed, falling back to CBC: $e');
|
||||
// Fallback to CBC with a warning
|
||||
try {
|
||||
final cbcEncrypter =
|
||||
encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc));
|
||||
final encrypted = cbcEncrypter.encrypt(plainText, iv: iv);
|
||||
return encrypted.base64;
|
||||
} catch (e2) {
|
||||
debugPrint('CBC Encryption Error: $e2');
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Decrypts a string
|
||||
/// ✅ FIX H-04: Decrypts a string (supports both GCM and legacy CBC)
|
||||
String decryptData(String encryptedText) {
|
||||
try {
|
||||
final encrypter =
|
||||
encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc));
|
||||
final encrypted = encrypt.Encrypted.fromBase64(encryptedText);
|
||||
return encrypter.decrypt(encrypted, iv: iv);
|
||||
// Check if it's GCM format
|
||||
if (encryptedText.startsWith(_gcmPrefix)) {
|
||||
final parts = encryptedText.substring(_gcmPrefix.length).split(':');
|
||||
if (parts.length != 2) {
|
||||
debugPrint('Invalid GCM format, falling back to CBC');
|
||||
return _decryptLegacyCbc(encryptedText);
|
||||
}
|
||||
final iv = encrypt.IV.fromBase64(parts[0]);
|
||||
final encrypted = parts[1];
|
||||
final gcmEncrypter =
|
||||
encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.gcm));
|
||||
return gcmEncrypter.decrypt(encrypt.Encrypted.fromBase64(encrypted),
|
||||
iv: iv);
|
||||
}
|
||||
// Legacy CBC format
|
||||
return _decryptLegacyCbc(encryptedText);
|
||||
} catch (e) {
|
||||
debugPrint('Decryption Error: $e');
|
||||
return '';
|
||||
// Try CBC as last resort
|
||||
try {
|
||||
return _decryptLegacyCbc(encryptedText);
|
||||
} catch (_) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Legacy CBC decryption (backward compatibility)
|
||||
String _decryptLegacyCbc(String encryptedText) {
|
||||
final cbcEncrypter =
|
||||
encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc));
|
||||
final encrypted = encrypt.Encrypted.fromBase64(encryptedText);
|
||||
return cbcEncrypter.decrypt(encrypted, iv: iv);
|
||||
}
|
||||
|
||||
/// Generate cryptographically secure random IV
|
||||
encrypt.IV _generateRandomIv(int length) {
|
||||
final random = Random.secure();
|
||||
final bytes = List<int>.generate(length, (_) => random.nextInt(256));
|
||||
return encrypt.IV(Uint8List.fromList(bytes));
|
||||
}
|
||||
}
|
||||
|
||||
r(String string) {
|
||||
|
||||
Reference in New Issue
Block a user