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 ...

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!
This is a small, yet powerful, Dart module that encrypts and decrypts data using the AES encryption standard. The module:
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.

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!
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.
// Using AES encryption with CBC mode (like a fancy encryption mode) and PKCS7 padding.
final encrypter = encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc, padding: 'PKCS7'));
// Now, encrypting the plain text
final encrypted = encrypter.encrypt(plainText, iv: iv);
// We add the salt and the encrypted bytes together, making sure it’s all safe.
final prefix = utf8.encode(\_saltedText); // Prepend our "Salted\_\_" text.
final cipherBytes = <int>\[\];
cipherBytes.addAll(prefix);
cipherBytes.addAll(salt); // Add the salt we generated.
cipherBytes.addAll(encrypted.bytes); // Add the encrypted data.
// Return the result as a URL-encoded base64 string (it’s like a neat package for safe transfer!)
final base64Cipher = base64Encode(cipherBytes);
return Uri.encodeComponent(base64Cipher); } 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?
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 ?
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 saltedPrefix = utf8.encode(\_saltedText); // Remember our prefix "Salted\_\_"?
final prefixBytes = cipherData.sublist(0, 8); // Get the first 8 bytes (the prefix).
if (!\_listEquals(prefixBytes, saltedPrefix)) {
throw FormatException("Invalid salt prefix, can't decrypt"); // If the salt doesn't match, throw an error.
} 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.
// Derive the key and IV again (same method as before).
final keyIV = \_deriveKeyAndIV(salt);
final key = encrypt.Key(Uint8List.fromList(keyIV.sublist(0, 32)));
final iv = encrypt.IV(Uint8List.fromList(keyIV.sublist(32, 48))); // 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?
The Result: You get the original text back, safe and sound, just like it was before encryption. Phew!

just placed this (out of context)
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 = [];
// The MD5 algorithm is used to hash and mix everything together.
while (derivedBytes.length < 48) {
final md5 = pc.MD5Digest(); // Using the MD5 hashing algorithm.
md5.update(Uint8List.fromList(previous), 0, previous.length);
md5.update(Uint8List.fromList(passphraseBytes), 0, passphraseBytes.length);
md5.update(Uint8List.fromList(salt), 0, salt.length);
final digest = Uint8List(md5.digestSize);
md5.doFinal(digest, 0);
derivedBytes.addAll(digest); // Add the hashed result to the key/IV list.
previous = digest; // Set the previous hash for the next round.
}
return derivedBytes; // Return the final key/IV. } 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?

By the time you finished reading, I was already in a deep sleep.
So, there you have it! This Dart encryption module is a superpower for protecting your data. It:
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!