
Crafted by AI because my creativity took a coffee break — only in images though, not in coding. Obviously. Duh. 🙄
Encryption is like the secret code that ensures only the right people can read your messages or access your data. In this blog, we’re going to explore a Dart-based encryption module that uses AES (Advanced Encryption Standard), one of the most popular encryption algorithms, to keep your data safe from prying eyes.
We’ll go step-by-step through the code, explaining everything in a fun yet professional way. Ready for your encryption adventure? Let’s get started!
What Is This Encryption Module All About?
This is a small, yet powerful, Dart module that encrypts and decrypts data using the AES encryption standard. The module:
- Encrypts plain text (like your passwords or messages) into unreadable ciphertext.
- Decrypts ciphertext back into the original plain text using a secret key (passphrase).
- Adds an extra layer of security with a random salt (a random string of data added to the encryption process).
- Uses a key and IV (Initialization Vector) derived from a passphrase to protect the data.
You might think, “What’s a salt, key, and IV?” Don’t worry! We’ll explain all these terms like we’re having a chat over coffee.

Breaking Down the Code: The Encryption Superpowers
Let’s start by exploring how the module works. Don’t worry if some of these terms seem like techno-babble; we’ll break it down in the simplest way possible!
1. Encrypting Data: Making Your Data Unreadable (Super Secret Code)
static String encryptData(String plainText) {
try {
final salt = _generateRandomBytes(8); // Salt to add some spice to our encryption!
final keyIV = _deriveKeyAndIV(salt); // Deriving the secret key and IV from our salt.
final key = encrypt.Key(Uint8List.fromList(keyIV.sublist(0, 32))); // First 32 bytes for the key.
final iv = encrypt.IV(Uint8List.fromList(keyIV.sublist(32, 48))); // Next 16 bytes for the IV.
} catch (e) {
snugLog("Encryption failed: $e", logType: LogType.error); // We log the error if something goes wrong.
return ''; // If it fails, we return an empty string (sad but true).
}
}
What’s happening here?
- Salt: This is like adding a little extra twist to your password to make it even harder to guess. We generate a random salt using _generateRandomBytes().
- Key & IV: These are like the secret ingredients for our encryption. We derive them from a passphrase using a special technique.
- Encrypting the Text: We use the AES algorithm in CBC mode (fancy stuff that shuffles the data around) and apply padding (PKCS7) to make sure the data fits neatly into blocks.
The Result: You get a URL-safe string that contains the encrypted version of your data. Even if someone intercepts it, they won’t be able to read it without the secret key.

isn’t it great ?
2. Decrypting Data: Unlocking the Secret Code
static String decryptData(String encodedCipher) {
try {
final rawBase64 = Uri.decodeComponent(encodedCipher); // Decode the URL-encoded base64 string.
final cipherData = base64Decode(rawBase64); // Decode the base64 string to get the cipher bytes.
final salt = cipherData.sublist(8, 16); // The next 8 bytes are our salt.
final encryptedBytes = cipherData.sublist(16); // The rest is the actual encrypted data.
// Now, decrypt the data using AES again.
final encrypter = encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc, padding: 'PKCS7'));
final decrypted = encrypter.decrypt(encrypt.Encrypted(Uint8List.fromList(encryptedBytes)), iv: iv);
return decrypted; // Return the decrypted text.
} catch (e) {
snugLog("Decryption failed: $e", logType: LogType.error); // Log the error.
return 'Decryption failed: Invalid key or corrupted data.'; // Return an error message.
}
}
What’s happening here?
- We reverse everything we did during encryption, but with one crucial step: we need the same salt and same key/IV to decrypt the data properly. If we don’t, the data is corrupted, and you’ll get a “Decryption failed” message.
- AES Decryption: Once we get the correct key and IV, we simply use the AES algorithm again to decrypt the ciphertext back into the original plain text.
The Result: You get the original text back, safe and sound, just like it was before encryption. Phew!

just placed this (out of context)
3. Key and IV Derivation: The Secret Recipe for Encryption
static List<int> _deriveKeyAndIV(List<int> salt) {
try {
final passphraseBytes = utf8.encode(dotenv.get('ENCRYPTION_PASSPHRASE')); // Our passphrase (from environment variables).
List<int> derivedBytes = [];
List<int> previous = [];
} catch (e) {
snugLog("Key derivation failed: $e", logType: LogType.error);
return List.filled(48, 0); // Return an empty key/IV in case of failure.
}
}
What’s happening here?
- Passphrase to Key: We turn the passphrase into a super secure key using a special algorithm (MD5). This ensures that even if someone guesses the passphrase, they can’t easily reverse the encryption.
- Key and IV: The result is a 48-byte array, with the first 32 bytes being the key and the next 16 bytes being the IV.

By the time you finished reading, I was already in a deep sleep.
Wrapping It Up: Supercharged Encryption in Dart!
So, there you have it! This Dart encryption module is a superpower for protecting your data. It:
- Encrypts data using a secure AES algorithm.
- Decrypts data with the same key and salt.
- Generates random salt and derives keys using a secret passphrase.
Whether you’re working on a Flutter app, or a backend server, or want to keep your data safe, this encryption module will have your back. Just remember: encryption is like a lock for your treasure chest — no one can open it without the key!
I hope this fun guide has helped you understand how to use encryption in Dart. Stay safe, keep coding, and always lock your secrets away with AES encryption!
Happy coding!
