import 'package:cryptography/cryptography.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'dart:convert'; class CryptoService { final _storage = const FlutterSecureStorage(); final algorithm = X25519(); final aesGcm = AesGcm.with256bits(); Future> initAccountSecurity(String masterPassword) async { // Генерируем пару X25519 ключей final keyPair = await algorithm.newKeyPair(); final publicKey = await keyPair.extractPublicKey(); final privateKeyBytes = await keyPair.extractPrivateKeyBytes(); // Сохраняем приватный ключ в Secure Storage await _storage.write( key: 'private_key', value: base64Encode(privateKeyBytes), ); // Шифруем приватный ключ с мастер-паролем (AES-GCM) final masterKey = await _deriveKeyFromPassword(masterPassword); final nonce = aesGcm.newNonce(); final encrypted = await aesGcm.encrypt( privateKeyBytes, secretKey: masterKey, nonce: nonce, ); // Комбинируем nonce и зашифрованные данные final encryptedData = nonce + encrypted.mac.bytes + encrypted.cipherText; final encryptedPrivateKey = base64Encode(encryptedData); final publicKeyBase64 = base64Encode(publicKey.bytes); return { 'public_key': publicKeyBase64, 'encrypted_private_key': encryptedPrivateKey, }; } Future decryptPrivateKey( String encryptedPrivateKey, String masterPassword, ) async { try { final encryptedData = base64Decode(encryptedPrivateKey); // Разделяем nonce и зашифрованные данные final nonce = encryptedData.sublist(0, 12); // GCM nonce = 12 bytes final macBytes = encryptedData.sublist(12, 28); final cipherText = encryptedData.sublist(28); final masterKey = await _deriveKeyFromPassword(masterPassword); final decrypted = await aesGcm.decrypt( SecretBox(cipherText, nonce: nonce, mac: Mac(macBytes)), secretKey: masterKey, ); return base64Encode(decrypted); } catch (e) { throw Exception('Неверный мастер-пароль или поврежденные данные'); } } Future _deriveKeyFromPassword(String password) async { final pbkdf2 = Pbkdf2( macAlgorithm: Hmac.sha256(), iterations: 10000, bits: 256, ); final salt = utf8.encode('chepuhagram_salt'); return await pbkdf2.deriveKeyFromPassword(password: password, nonce: salt); } Future deriveSharedSecret( String myPrivateKeyBase64, String theirPublicKeyBase64, ) async { final myKeyPair = await algorithm.newKeyPairFromSeed(base64Decode(myPrivateKeyBase64)); final theirPublicKey = SimplePublicKey( base64Decode(theirPublicKeyBase64), type: KeyPairType.x25519, ); return await algorithm.sharedSecretKey( keyPair: myKeyPair, remotePublicKey: theirPublicKey, ); } Future encryptMessage(String text, SecretKey sharedKey) async { final nonce = aesGcm.newNonce(); final encrypted = await aesGcm.encrypt( utf8.encode(text), secretKey: sharedKey, nonce: nonce, ); // Сохраняем Nonce + MAC + CipherText для передачи return base64Encode(nonce + encrypted.mac.bytes + encrypted.cipherText); } Future decryptMessage(String base64Data, SecretKey sharedKey) async { final data = base64Decode(base64Data); final nonce = data.sublist(0, 12); final mac = data.sublist(12, 28); final cipherText = data.sublist(28); final decrypted = await aesGcm.decrypt( SecretBox(cipherText, nonce: nonce, mac: Mac(mac)), secretKey: sharedKey, ); return utf8.decode(decrypted); } Future getPrivateKey() async { return await _storage.read(key: 'private_key'); } Future hasPrivateKey() async { final key = await _storage.read(key: 'private_key'); return key != null; } Future savePrivateKey(String privateKey) async { await _storage.write(key: 'private_key', value: privateKey); } Future deletePrivateKey() async { await _storage.delete(key: 'private_key'); } }