Flutter / Dart : Avoid storing password in plain text
Solution 1
It is generally not a good idea to store passwords in plain text anywhere. The way you handle passwords, though, depends on the platform.
Flutter
The flutter_secure_storage package uses Keychain on iOS and KeyStore on Android to store passwords (or tokens).
// Create storage
final storage = FlutterSecureStorage();
// Read secret
String value = await storage.read(key: key);
// Write secret
await storage.write(key: key, value: value);
Note that for Android the min API is 18.
Dart Server
If you are making a server, it is even more important not to store the user passwords in plain text. If the server is compromised, the attacker would have access to all of the passwords, and many users use the same password on multiple accounts.
It would be best to hand the authentication over to Google or Facebook or some other trusted third party by using OAuth2. However, if you are doing your own authorization, you should hash the passwords with a salt and save the hash, not the password itself. This makes it more difficult for an attacker to get the user passwords in case the server is compromised.
A basic implementation could use the crypto package by the Dart Team.
// import 'package:crypto/crypto.dart';
// import 'dart:convert';
var password = 'password123';
var salt = 'UVocjgjgXg8P7zIsC93kKlRU8sPbTBhsAMFLnLUPDRYFIWAk';
var saltedPassword = salt + password;
var bytes = utf8.encode(saltedPassword);
var hash = sha256.convert(bytes);
Save the salt and the hash. Discard the password. Use a different salt for every user.
To make brute forcing the hashes more difficult, you can also check out the dbcrypt package.
Solution 2
If you want to hash
Use the password_hash package. Their example code is very easy to use:
var generator = new PBKDF2();
var salt = Salt.generateAsBase64String();
var hash = generator.generateKey("mytopsecretpassword", salt, 1000, 32);
Store both the hash
and the salt
, and you can verify someone else's password attempt by running the generator.generateKey
function using their password and the saved salt.
What you actually want
If you're trying to automatically login, you of course need the original password, not a hash. You have a couple options
If the device that will have your app installed is safe, as in it is some company-owned device that has to be logged into by an employee, then have it in plaintext. It doesn't matter. As any company's security policy should be, you must make sure that hard drives are wiped before disposing of electronics (And make sure that no one can stroll in and take the iPad or whatever it is).
If unknown people outside of your organization will be installing your app, you will have to have them login and use their email, or have an API open that will send emails on their behalf (To prevent spamming from your email). The app would sent a POST to that API to send an email. If you had the plaintext password in the application, they could find it on their device, and abuse it.
Related videos on Youtube
Comments
-
Zeusox over 1 year
I am using Dart mailer in Flutter and there is a comment that says:
How you use and store passwords is up to you. Beware of storing passwords in plain.
Is there any way to hash the password? How can I avoid storing it in plain text?
-
ZeusoxI am not using this for authentication. I am trying to send emails using Dart Mailer Package and they note not to store passwords in plain ? Please check this link out to kinda see what I am talking about. Thanks, pub.dartlang.org/packages/mailer
-
-
Zeusox over 5 yearsIt does not work? When I use the hash package, the Gmail smtp says I have wrong credentials ?
-
Nicholas Pipitone over 5 yearsI don't understand, what are you doing?
-
Zeusox over 5 yearsI am using Dar mailer as in pub.dartlang.org/packages/mailer . and they note to store the password in plain ? How can I avoid that ?
-
Nicholas Pipitone over 5 yearsWhat exactly are you doing though? On a high level, what are you trying to accomplish with your app?
-
Zeusox over 5 yearsThis app takes in users feedback and stores it on a Firestore Database. When the store process is complete, I automatically send an email to our service email with all the data that was stored on the Database.
-
Nicholas Pipitone over 5 yearsAh, and you want it to automatically login via SMTP and send the email. Is this running on a user's application (ie on their device, not your server)?
-
boformer over 5 yearsthat's a very bad idea. is there no way to send emails directly from firebase, or let firebase trigger some email service?
-
Guido Spadavecchia almost 3 yearsYou are still hardcoding the password in the code, which can be discovered if decompiled.