Flutter / Dart : Avoid storing password in plain text

11,794

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

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

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

Share:
11,794

Related videos on Youtube

Zeusox
Author by

Zeusox

Coding is art, art is coding !

Updated on September 15, 2022

Comments

  • Zeusox
    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?

    • Zeusox
      Zeusox
      I 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
    Zeusox over 5 years
    It does not work? When I use the hash package, the Gmail smtp says I have wrong credentials ?
  • Nicholas Pipitone
    Nicholas Pipitone over 5 years
    I don't understand, what are you doing?
  • Zeusox
    Zeusox over 5 years
    I 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
    Nicholas Pipitone over 5 years
    What exactly are you doing though? On a high level, what are you trying to accomplish with your app?
  • Zeusox
    Zeusox over 5 years
    This 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
    Nicholas Pipitone over 5 years
    Ah, 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
    boformer over 5 years
    that's a very bad idea. is there no way to send emails directly from firebase, or let firebase trigger some email service?
  • Guido Spadavecchia
    Guido Spadavecchia almost 3 years
    You are still hardcoding the password in the code, which can be discovered if decompiled.