Hone logo
Hone
Problems

Secure Password Hashing in Python

In the realm of web security and data protection, storing user passwords in plain text is a critical vulnerability. This challenge focuses on implementing a secure password hashing mechanism in Python, a fundamental practice for protecting sensitive user credentials. You will learn to use a robust hashing algorithm to transform passwords into a secure, one-way representation, making it significantly harder for attackers to compromise user accounts even if your database is breached.

Problem Description

Your task is to implement a Python function that securely hashes a given password. This involves using a strong, industry-standard hashing algorithm that includes salting to prevent common attacks like rainbow table lookups.

Requirements:

  1. Hashing Algorithm: You must use a modern, secure password hashing algorithm. The argon2-cffi library is highly recommended for its state-of-the-art security features. If you prefer, bcrypt is also an acceptable alternative. Avoid older, less secure algorithms like MD5 or SHA-1.
  2. Salting: The hashing process must automatically generate and incorporate a unique salt for each password. This salt should be stored along with the hash.
  3. Verification: You need to implement a function to verify if a given password matches a stored hash (which includes the salt).
  4. Function Signatures:
    • hash_password(password: str) -> str: This function should take a plain-text password and return a securely hashed string representation.
    • verify_password(password: str, hashed_password: str) -> bool: This function should take a plain-text password and the stored hashed password (including the salt) and return True if they match, False otherwise.

Expected Behavior:

  • hash_password should always produce a different hash output for the same password if called multiple times (due to unique salting).
  • verify_password should return True when given the original password and its corresponding hash.
  • verify_password should return False when given an incorrect password and its corresponding hash.
  • verify_password should correctly handle different hash formats generated by the chosen library.

Edge Cases to Consider:

  • Empty passwords.
  • Passwords with special characters, whitespace, or unusual encoding.
  • The output of hash_password must be a single string that can be stored and later used for verification.

Examples

Example 1:

Input:
password = "mysecretpassword123"

Output:
# The output will be a string representing the salt and hash, e.g.:
# $argon2id$v=19$m=65536,t=3,p=4$yourgeneratedsalt$yourgeneratedhash
# (Actual output format depends on the library used and specific parameters)

Explanation:
The `hash_password` function takes the plain-text password and generates a unique salt, then hashes the password with the salt. The output is a single string containing both the salt and the hash, encoded in a format recognizable by the verification function.

Example 2:

Input:
password = "mysecretpassword123"
hashed_password = "$argon2id$v=19$m=65536,t=3,p=4$yourgeneratedsalt$yourgeneratedhash" # (This would be the output from Example 1)

Output:
True

Explanation:
The `verify_password` function extracts the salt from the `hashed_password` string, hashes the provided `password` with that extracted salt, and compares the resulting hash with the hash stored within `hashed_password`. Since the password and salt match, it returns `True`.

Example 3:

Input:
password = "wrongpassword"
hashed_password = "$argon2id$v=19$m=65536,t=3,p=4$yourgeneratedsalt$yourgeneratedhash" # (Hash from Example 1)

Output:
False

Explanation:
Even though `hashed_password` contains a valid hash, the `verify_password` function correctly identifies that the provided `password` ("wrongpassword") does not match the original password that generated the hash, returning `False`.

Constraints

  • The input password will be a string.
  • The output of hash_password must be a single string.
  • The hashed_password input to verify_password will be a string generated by hash_password from the same chosen library.
  • The hashing process should be computationally intensive enough to deter brute-force attacks, but fast enough for reasonable user experience during login. The default or recommended parameters of argon2-cffi or bcrypt are generally suitable.

Notes

  • Library Choice: For this challenge, it is strongly recommended to use the argon2-cffi library. You can install it using pip: pip install argon2-cffi. If you choose bcrypt, install it with pip install bcrypt.
  • Parameters: Password hashing algorithms have various tunable parameters (e.g., memory cost, time cost, parallelism). For this challenge, you can use the library's default or recommended parameters. Understanding these parameters is crucial for production systems, but for this exercise, focusing on correct implementation with salting and verification is key.
  • Storage: The output of hash_password is what you would store in your database for each user. Never store plain-text passwords.
  • Security Best Practices: Always keep your hashing libraries updated to benefit from the latest security research and improvements.
Loading editor...
python