In the world of mobile app development, security is paramount. Ensuring the safety of user data is not only a legal and ethical obligation but also a critical aspect of building trust with your audience. One common method of storing data locally in Flutter apps is by using SharedPreferences. However, as we discovered during our own development journey, these values are not entirely immune to potential threats. In this article, we will discuss the vulnerabilities of SharedPreferences and present an encryption method to bolster the security of your Flutter app.
Understanding the Vulnerabilities
SharedPreferences in Flutter are a convenient way to store simple pieces of data, such as user preferences or authentication tokens, directly on the user’s device. However, these values are stored in plain text, making them susceptible to unauthorized access. Should a malicious actor gain access to the device or the app’s data storage, they could easily view and manipulate these stored values, potentially compromising sensitive information.
Encrypting a value with SharedPreferences
To mitigate these risks, we recommend encrypting the data stored in SharedPreferences. Encryption is a process that converts plain text data into a cipher or code that can only be deciphered with the appropriate decryption key. By implementing encryption, even if an unauthorized party gains access to the data, they will be unable to decipher it without the decryption key.
Below, we provide a simple example of how to encrypt and decrypt data stored in SharedPreferences within your Flutter app:
const String iv = "aRandomStringForEncryption";
String decryptWithAES(String key, Encrypted encryptedData) {
final cipherKey = Key.fromUtf8(key);
final encryptService = Encrypter(AES(cipherKey, mode: AESMode.cbc));
final initVector = IV.fromUtf8(iv);
return encryptService.decrypt(encryptedData, iv: initVector);
}
Encrypted encryptWithAES(String key, String plainText) {
final cipherKey = Key.fromUtf8(key);
final encryptService = Encrypter(AES(cipherKey, mode: AESMode.cbc));
final initVector = IV.fromUtf8(iv);
Encrypted encryptedData = encryptService.encrypt(plainText, iv: initVector);
return encryptedData;
}
void saveStringToLocalStorage(String valueToSave) async {
final prefs = await SharedPreferences.getInstance();
Encrypted encrypted = encryptWithAES(key, valueToSave);
String encryptedString = encrypted.base64;
prefs.setString('key', encryptedString);
}
Future<String?> getStringFromLocalStorage() async {
final prefs = await SharedPreferences.getInstance();
String? encryptedString = prefs.getString('key');
if (encryptedString == null) {
return '';
}
Encrypted encrypted = Encrypted.fromBase64(encryptedString);
String decryptedText = decryptWithAES(key, encrypted);
return decryptedText;
}
This code utilizes the Flutter Secure Storage plugin and the Encrypt package to encrypt and decrypt data stored in SharedPreferences. Be sure to replace 'iv'
with a strong, unique encryption key.
Conclusion
Security should always be a top priority during app development. By encrypting the data stored in SharedPreferences, you add an extra layer of protection against potential threats. While this method enhances security, it’s important to remember that no system is entirely impervious to attacks. However, taking proactive steps to safeguard user data demonstrates your commitment to their privacy and security.
Implementing encryption in your Flutter app is a proactive measure that not only safeguards sensitive data but also enhances your app’s credibility. By securing SharedPreferences, you are actively working towards building trust with your users and ensuring the long-term success of your application.