Course contentsShow
← Databases & SQL
Lesson 1596 of 1,95315. Database Security and GovernanceFree lesson

Hashing Sensitive Identifiers

You will be able to implement salt-based hashing for data points like PII or user identifiers.

In this lesson, you will learn how to implement salt-based hashing to protect sensitive identifiers like PII, ensuring that even if your database is compromised, individual records cannot be easily deanonymized via pre-computed attacks.

Why Hashing Isn't Enough

When dealing with identifiers (such as national ID numbers or email addresses), a simple hash like SHA-256 is insufficient. Attackers use "rainbow tables"—pre-computed databases of hashes for every common input—to reverse your identifiers instantly. To mitigate this, we use a salt: a unique, random string appended to the identifier before hashing.

Implementing Salted Hashing

The goal is to store a unique salt for each row, then hash the combination of the salt and the sensitive_identifier. This forces the attacker to compute a new rainbow table for every single row in your database, which is computationally infeasible.

Consider this table structure:

-- Storing the salt alongside the hashed identifier
CREATE TABLE user_identities (
    user_id UUID PRIMARY KEY,
    salt CHAR(32),
    hashed_pii CHAR(64)
);

When an application receives an identifier, it performs the following steps:

  1. Retrieve or Generate: Fetch the salt for the user. If creating a new record, generate a cryptographically secure random string.
  2. Concatenate: combined_string = salt + sensitive_identifier.
  3. Hash: final_hash = SHA256(combined_string).
  4. Store: Save the salt and the final_hash in the database.

The Trade-off

Hashing is a one-way function. By hashing a sensitive identifier, you effectively lose the ability to perform range scans (e.g., "find all users born in 1990") or pattern matches (e.g., "find all emails ending in @company.com") on that specific field. You can only perform exact match lookups by applying the same salt and hashing process to the input provided by the user at runtime.

If your application requires the ability to reconstruct the original identifier, you should refer back to your knowledge of field-level encryption rather than hashing. Use hashing specifically when you need to verify an identity without ever exposing the raw, underlying data.

Key Takeaway: Always pair your hashing strategy with a unique, row-level salt to defeat rainbow table attacks and ensure your sensitive identifiers remain computationally resistant to reverse engineering.