Question

Hello another newbie question for all the database/web experts out there....

I have read a lot about protecting passwords stored in a database using hashes, salts, encryption algorithms etc. To avoid confusion I'm saying there is two different passwords... 'database username/password' and 'application username/password' of which there will be many.

I think this is correct... but as my application will potentially have many users, I will not be creating a new database user for each person, rather they can all use the same database uername/password to access the database itself. The options will be quite restrictive. The application account settings (username and password) will be encrypted in a table in the database.

What I want to know is if/how can I use the password to prevent the user from reading any entries in the database.

It might better be explained by an example:

Say I have a system with 20 users. I will allocate a (application) username and password to each.

Each one will generate some data from a PC application remotely, then upload it to the database. Each row in the table will have a reference/column to the 'user' who uploaded it (for retrieval at a later date).

Suppose somebody comes along (trying to hack the system) and instead of using their own username starts using a different one and even executing other sql commands to read the other table entries.

How do I code an application (which platform) to ensure that the user accessing the database only has access to their own data.

I'm sure that this has been done by developers many times prevously, but if anyone can point me in the right direction to some example code or tutorials that would be much apprectiated.

Ta Muchly!!!

Was it helpful?

Solution

  • Do not use a single pass of any hashing function to store passwords.
  • Do not fail to use a random salt in the 8-16 byte range.

Instead, your application has a user is select a keyword/passphrase:

  • Generate a cryptographically random 8-16 byte salt
  • Use PBKDF2, BCrypt, or SCrypt with said salt and as large an iteration count/work factor as your processors can handle to create a password hash
    • If you use PBKDF2 in specific, do not request a larger output than the native hash size (SHA-1 = 20 bytes, SHA-256 is 32 bytes, SHA-384 is 48 bytes, and SHA-512 is 64 bytes), or you increase the comparative advantage an attacker has over you, the defender.

Then in your database, your application stores that user's particular:

  • Salt in the clear
    • a BINARY(8) or BINARY(16) column
  • Iteration count/work factor
    • an INT UNSIGNED column
    • So you can easily change/upgrade it later
  • Resulting password hash
    • perhaps a BINARY(20) column for any 20 byte output length PBKDF2-HMAC-SHA-x, or a BINARY(24) for the 192 bits of BCrypt, or BINARY(64) for the native output size of PBKDF2-HMAC-SHA-512
    • Alternately, you can Base64 encode the binary output of PBKDF2/BCrypt/SCrypt, but then you must be sure to either use a case sensitive comparison or Base64 decode it after retrieval
  • Version of authentication protocol - this would be 1, or perhaps 0.
    • a TINYINT UNSIGNED column
    • So you can easily change/upgrade it later if you move from this method to NewWellKnownMethod later

When the user wants to authenticate to your system, you:

  • Retrieve their version, salt, iteration count/work factor, and resulting hash from the database
  • Hash whatever keyword/password they just entered with the salt and iteration count/work factor from the database.
  • Compare the result you just got with what was in the database; if they're the same, let them in.
    • Advanced: use a constant time compare, so it doesn't just quit trying if the first byte is different, to reduce the vulnerability to timing attacks.

After you've authenticated the user, you'll need to look that user up in some permissions table and determine what they're allowed to do, or use their application level username as a parameter for every query the application executes to ensure they're only retrieving their own data.

Please read How to securely hash passwords?, of which Thomas Porrin's answer is currently the most commonly referred to Stackexchange treatise on password hashing, and certainly the best I've seen so far.

OTHER TIPS

Use an MD5 hash of the password - never store the original password. You could also add in the user name to confound dictionary attacks. Then associate the data with a user by means of a user_id field in any data. Paul...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top