Created
May 20, 2024 03:30
-
-
Save ffkev/6d72e2220720d714eba15af4264bcec1 to your computer and use it in GitHub Desktop.
AES gmc Encryption / Decryption logic in Flutter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:convert'; | |
import 'dart:typed_data'; | |
import 'package:encrypt/encrypt.dart' as encrypt; | |
import 'package:flutter/material.dart'; | |
import 'package:flutter/services.dart'; | |
void main() { | |
runApp(EncryptionApp()); | |
} | |
class EncryptionApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Encryption App', | |
theme: ThemeData( | |
primarySwatch: Colors.blue, | |
), | |
home: EncryptionPage(), | |
); | |
} | |
} | |
class EncryptionPage extends StatefulWidget { | |
@override | |
_EncryptionPageState createState() => _EncryptionPageState(); | |
} | |
class _EncryptionPageState extends State<EncryptionPage> { | |
final TextEditingController _contentController = TextEditingController(); | |
final TextEditingController _aesKeyController = TextEditingController(); | |
final TextEditingController _encryptedDataController = TextEditingController(); | |
final TextEditingController _decryptionKeyController = TextEditingController(); | |
String _encryptedData = ''; | |
String _decryptedData = ''; | |
Future<void> _encrypt() async { | |
final content = _contentController.text; | |
final aesKey = _aesKeyController.text; | |
if (content.isEmpty || aesKey.isEmpty) { | |
setState(() { | |
_encryptedData = 'Content and AES key cannot be empty'; | |
}); | |
return; | |
} | |
try { | |
final key = encrypt.Key(Uint8List.fromList(base64Decode(aesKey))); | |
final iv = encrypt.IV.fromSecureRandom(12); // AES-GCM typically uses a 12-byte IV | |
final encrypter = encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.gcm)); | |
final encrypted = encrypter.encrypt(content, iv: iv); | |
final gcm = encrypted.bytes; | |
// Split ciphertext and tag | |
final ciphertext = gcm.sublist(0, gcm.length - 16); | |
final tag = gcm.sublist(gcm.length - 16); | |
final ciphertextb64 = base64Encode(ciphertext); | |
final nonceb64 = base64Encode(iv.bytes); | |
final tagb64 = base64Encode(tag); | |
final finalData = '$ciphertextb64~$nonceb64~$tagb64'; | |
setState(() { | |
_encryptedData = finalData; | |
}); | |
} catch (e) { | |
setState(() { | |
_encryptedData = 'Encryption error: $e'; | |
}); | |
} | |
} | |
Future<void> _decrypt() async { | |
final encryptedData = _encryptedDataController.text; | |
final aesKey = _decryptionKeyController.text; | |
if (encryptedData.isEmpty || aesKey.isEmpty) { | |
setState(() { | |
_decryptedData = 'Encrypted data and AES key cannot be empty'; | |
}); | |
return; | |
} | |
try { | |
final key = encrypt.Key(Uint8List.fromList(base64Decode(aesKey))); | |
final parts = encryptedData.split('~'); | |
final ciphertext = base64Decode(parts[0]); | |
final nonce = base64Decode(parts[1]); | |
final tag = base64Decode(parts[2]); | |
final combinedData = Uint8List(ciphertext.length + tag.length) | |
..setAll(0, ciphertext) | |
..setAll(ciphertext.length, tag); | |
final encrypter = encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.gcm)); | |
final iv = encrypt.IV(nonce); | |
final decrypted = encrypter.decrypt64(base64Encode(combinedData), iv: iv); | |
setState(() { | |
_decryptedData = decrypted; | |
}); | |
} catch (e) { | |
setState(() { | |
_decryptedData = 'Decryption error: $e'; | |
}); | |
} | |
} | |
void _copyToClipboard(String text) { | |
Clipboard.setData(ClipboardData(text: text)); | |
ScaffoldMessenger.of(context).showSnackBar( | |
SnackBar(content: Text('Copied to clipboard')), | |
); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: Text('Encryption App'), | |
), | |
body: SingleChildScrollView( | |
padding: const EdgeInsets.all(16.0), | |
child: Column( | |
children: [ | |
TextField( | |
controller: _contentController, | |
decoration: InputDecoration(labelText: 'Content to Encrypt'), | |
), | |
TextField( | |
controller: _aesKeyController, | |
decoration: InputDecoration(labelText: 'AES Key for Encryption'), | |
), | |
SizedBox(height: 20), | |
ElevatedButton( | |
onPressed: _encrypt, | |
child: Text('Encrypt'), | |
), | |
SizedBox(height: 20), | |
SelectableText( | |
'Encrypted Data: $_encryptedData', | |
style: TextStyle(fontSize: 16), | |
), | |
ElevatedButton( | |
onPressed: () => _copyToClipboard(_encryptedData), | |
child: Text('Copy Encrypted Data'), | |
), | |
Divider(), | |
TextField( | |
controller: _encryptedDataController, | |
decoration: InputDecoration(labelText: 'Encrypted Data'), | |
), | |
TextField( | |
controller: _decryptionKeyController, | |
decoration: InputDecoration(labelText: 'AES Key for Decryption'), | |
), | |
SizedBox(height: 20), | |
ElevatedButton( | |
onPressed: _decrypt, | |
child: Text('Decrypt'), | |
), | |
SizedBox(height: 20), | |
SelectableText( | |
'Decrypted Data: $_decryptedData', | |
style: TextStyle(fontSize: 16), | |
), | |
ElevatedButton( | |
onPressed: () => _copyToClipboard(_decryptedData), | |
child: Text('Copy Decrypted Data'), | |
), | |
], | |
), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment