Blog | G5 Cyber Security

Database Password Security: Why Not Just Store Passwords as a ‘Password’ Type?

TL;DR

Databases generally don’t have a specific ‘password’ data type because storing passwords directly, even in seemingly secure ways, is risky. Modern cyber security best practice involves hashing and salting passwords before storage, which requires more flexible data types like strings or binary blobs. Using dedicated password types could lead to vulnerabilities if not implemented with extreme care.

Why Databases Don’t Offer a ‘Password’ Data Type

  1. Security Through Obscurity is Insufficient: Simply labelling a column as ‘password’ doesn’t make it secure. Attackers know where to look, and the database itself isn’t protecting the password – just its location.
    • A dedicated type might encourage developers to think security is handled automatically, leading to complacency.
  2. Hashing & Salting are Essential: Passwords should never be stored in plain text. The standard approach is:
    • Hashing: A one-way function transforms the password into a fixed-size string of characters.
    • Salting: A random value (the ‘salt’) is added to each password before hashing, making rainbow table attacks much harder.
  3. Flexible Data Types are Needed for Hashing: Hash algorithms produce strings or binary data – not a special ‘password’ type.
    • Commonly used types include VARCHAR (for storing the hash as text) and VARBINARY (for storing the hash in its raw binary form).
  4. Algorithm Flexibility: Password hashing algorithms evolve. A dedicated type would need constant updates to support new, more secure algorithms.
    • Using a general-purpose string or blob allows you to change the hashing algorithm without major database schema changes.

How Passwords *Should* Be Stored

  1. Choose a Strong Hashing Algorithm: Use modern algorithms like bcrypt, Argon2, or scrypt.
    • Avoid older algorithms like MD5 and SHA1 – they are easily cracked.
  2. Generate Unique Salts for Each Password: The salt should be long enough (at least 16 bytes) and randomly generated.
    -- Example using a random function in PostgreSQL:
    SELECT gen_salt('bf', 8);
  3. Store the Salt Alongside the Hash: You need to store both the hash *and* the salt to verify passwords later. Typically, this is done in separate columns.
    • Example table structure:
      Column Name Data Type
      user_id INTEGER PRIMARY KEY
      password_hash VARCHAR(255)
      password_salt VARCHAR(32)
  4. Password Verification: When a user logs in, hash the entered password with their stored salt and compare it to the stored hash.
    -- Simplified example (pseudocode):
    hashed_input = hash(password + salt);
    if hashed_input == stored_hash:
      # Password matches!
    else:
      # Incorrect password.

Potential Risks of a ‘Password’ Data Type (If It Existed)

  1. Vendor Lock-in: A proprietary type could make migrating databases more difficult.
  2. Hidden Complexity: Users might assume the type handles all security aspects, leading to misconfiguration or weak implementations.
  3. Limited Control: You’d have less control over the hashing algorithm and salt generation process.
Exit mobile version