Skip to main content

Security & Hashing

A. The Problem with Passwords

Most applications use a username and password for authentication because they are familiar and easy to use.

However, passwords have several security problems:

  • They can be guessed
  • They can be stolen
  • Credentials can potentially be intercepted
  • Humans tend to create predictable passwords
  • People often reuse similar passwords

Security is not only a computer science problem — it's also a human behavior problem.

Key idea: A password that feels unpredictable to a human may still be very predictable to a computer.

B. Dictionary Attacks

A dictionary attack tries common words, passwords, and predictable variations.

Examples:

password
password123
p@ssword
onomatopoeia564

Humans often try to make passwords look random by:

  • Adding numbers
  • Replacing letters with symbols
  • Using common words with small modifications

However, attackers already know these patterns.

A better approach is to use long, computer-generated random passwords.

Key idea: Humans are bad at creating truly random passwords.

C. Why SSH Keys?

For server authentication, the course uses an SSH key instead of relying only on a username and password.

If someone gains access to your server credentials, they may gain control over the entire server.

The instructor says:

"So what we're going to use is, we're going to use an SSH key."

Key idea: Server access requires strong authentication because compromising the server can give an attacker significant control.

D. What Is Hashing?

A hash function takes input data, runs it through a mathematical function, and produces an output called a hash.

Example:

Hashing can also be used for verification, such as checking whether a file has been changed.

If the file changes, its hash will also change.

Key idea: A hash function transforms input data into a hash value.

E. Hashing Is Deterministic

A hash function is deterministic.

This means:

The same input passed through the same hash function produces the same output.

This property is useful for comparing hashes, but it creates a problem when people use common passwords.

Key idea: Hashing the same value again doesn't make it different.

F. Rainbow Tables

Because hashes are deterministic, attackers can calculate the hashes of common passwords in advance.

For example:

password → hash_A
password123 → hash_B
123456 → hash_C
qwerty → hash_D

These precomputed password/hash mappings can be used to quickly identify common passwords.

The instructor describes this using a Rainbow Table.

Example:

Instead of trying to reverse the hash function, the attacker can compare the hash against values that were already calculated.

Key idea: Rainbow Tables use precomputed hashes of likely inputs to identify matching passwords.


G. MD5 → SHA-1 → SHA-256

The instructor introduces several hashing algorithms:

MD5

MD5 was historically used for cryptographic hashing.

However, MD5 is no longer considered appropriate for password security.

SHA-1

SHA-1 produces a longer hash than MD5.

However, simply switching algorithms does not solve the fundamental problem:

Common password hashes can still be precomputed.

SHA-256

SHA-256 is a stronger general-purpose cryptographic hash than MD5 or SHA-1, but it is designed to run quickly. That speed makes it unsuitable for storing passwords directly because an attacker can test many password guesses per second.

The instructor points out:

"We're still not there yet. That's still not very secure."

The fundamental problem remains:

Key idea: A stronger general-purpose hash function alone does not make password storage safe. Passwords need a deliberately slow password-hashing algorithm.

H. Salt

A salt is random data added to a password before hashing.

Without salt:

With salt:

For example:

Another user could have the exact same password but a different salt:

Therefore:

Salt is generated randomly by a secure random number generator and stored alongside the hash in the database.

This makes precomputed Rainbow Tables much less useful because each unique salt produces a different hash. However, if an attacker steals both the salt and hash, they can still test password guesses for that individual account.

Key idea: Salt adds randomness before hashing so identical passwords don't simply produce identical stored hashes.


I. Use a Password-Hashing Algorithm

Applications should store passwords with a purpose-built password-hashing algorithm such as Argon2id, scrypt, bcrypt, or PBKDF2, rather than applying MD5, SHA-1, or SHA-256 directly.

These algorithms are intentionally expensive to run. A configurable cost factor makes each password guess slower and more costly for an attacker. Modern password-hashing libraries also generate and store a unique salt with each hash.

Use a well-maintained authentication library and follow its current recommendations instead of assembling this process manually.

Key idea: Salt prevents reuse of precomputed hashes, while a slow password-hashing algorithm makes each new guess expensive.


J. Randomness Is Hard

Adding a salt introduces randomness into the hashing process.

However, generating security-sensitive random values correctly requires a cryptographically secure random number generator. Applications should use the operating system or a trusted security library rather than trying to create randomness themselves.

Humans often think they are being random, but we naturally create patterns.

The same idea applies to computer-generated values: complicated-looking output does not automatically mean that it is cryptographically secure.

Key idea: Something that looks random is not necessarily secure randomness.


K. Don't Roll Your Own Security

The instructor gives an important rule:

"Don't roll your own security. Don't roll your own hash function."

Developers should not create their own cryptographic algorithms or security mechanisms.

A custom algorithm may appear difficult to understand but still contain predictable patterns or vulnerabilities.

Key idea: Don't invent your own cryptography. Use established and tested security mechanisms.


L. Why This Matters for Developers

Security mistakes can happen when developers assume that something is secure simply because it looks complicated or random.

Cryptography and security are specialized fields, so developers should rely on established cryptographic standards and tools instead of designing their own.

Key idea: Security should be based on proven cryptography, not on whether an algorithm looks difficult to break.

M. The Security Flow

The entire problem can be understood as:

Most Important Concepts

  • Dictionary Attack

    • Tries common passwords and predictable patterns.
  • Hash Function

    • Transforms input data into a hash.
  • Password-Hashing Algorithm

    • Uses salt and a configurable cost to make password guesses expensive.
  • Deterministic

    • Same input + same hash function → same output.
  • Rainbow Table

    • Uses precomputed hashes to identify likely original inputs.
  • Salt

    • Adds random data before hashing.
  • Salted Hash

    • Makes the same password produce different hashes when different salts are used.

Core idea: General-purpose hashing alone is not enough for password security. Use a proven password-hashing algorithm with a unique salt and an appropriate cost factor.