title: Securely Storing Database Password
body: <p>I'd like to randomly generate an encryption key and password for an SQL Server CE database when it's created, and then save the key in some secure way that would allow the program to open a connection, but not be easily reachable by potential attackers.</p>
  
  <p>I'm working on an offline WPF application that stores certain user and setting information in a local database.</p>
  
  <p>My current implementation is to have one "Device Password" that the user sets up which is used as the encryption key for the generated SQL Server CE database password. The base64 encrypted database password is then saved in a simple .txt settings file. When the application starts up, the user enters the Device Password and that string is used as the decryption key for the saved password. If the resulting string is able to open a connection to the database, the password was correct and the program is opened with full access.</p>
  
  <p>What I'm trying to do now is modify the system to allow multiple users with specific Username/Password credentials to open the program and access the database with varying levels of privilege. The way that I'm trying to achieve this is by handling the user authentication separately, and opening the database regardless of the credentials to load some basic application info.</p>
  
  <p>Below is roughly my current implementation:</p>
  
  <pre><code>        var candidateDBPwd = DecryptDatabasePassword(passwordBox.Password, Settings.Instance.EncryptedDatabasePassword);
  
          if (candidateDBPwd.IsNullOrEmpty())
          {
              // User's password didn't decrypt database password.
              return false;
          }
  
          if (File.Exists(Constants.DB_FILE))
          {
              // Normal operation: Try to open the database file to see that 
              // we've got the correct password.
              string databaseArguments = Constants.DB_ARGS_SECURE + candidateDBPwd;
              using (var conn = new SqlCeConnection(databaseArguments))
              {
                  try
                  {
                      conn.Open();
                  }
                  catch (System.Data.SqlServerCe.SqlCeException ex)
                  {
                      // Failed to open the database: User's password must have been wrong!
                      return false;
                  }
              }
  </code></pre>
  
  <p>I've spent the past few hours researching similar issues and am now beginning to wonder if it's possible. Consensus seems to state that storing passwords or connectionStrings in the App.config file is futile because if you encrypt the sections, you still need to store that key somewhere in code. Most of the existing SO threads on the issue seem to be several years out of date and it seems that that practice has deprecated. Is there some new respectable way to store a local database password? Or would you recommend a different approach to implementing the feature?</p>