The script is designed to check if passwords have been exposed in data breaches and whether they are part of a list of commonly used passwords. It uses the Have I Been Pwned (HIBP) API for breach data and checks local files for common passwords. This Python script evaluates the security of passwords by checking against two sources: a local list containing 1000 passwords generated by ChatGPT and an external API known as HIBP (Have I Been Pwned). The script uses k-anonymity – a model for protecting privacy, meaning that passwords are encrypted with the SHA-1 algorithm, and only the first 5 characters are used to query the HIBP API, eliminating the possibility of a man-in-the-middle attack.
This is how it works:
-
Functionality:
- The script processes each password provided as an argument.
- It first checks if the password is in a locally stored file of common passwords.
- If not found in the local list, it queries HIBP using the first 5 characters of the SHA-1 hash of the password.
-
API Integration:
- The script uses the
requestslibrary to make HTTP requests to the HIBP API. - It constructs a URL based on the first 5 characters of the hashed password and retrieves the response.
- The script uses the
-
Hashing:
- Passwords are converted into SHA-1 hashes using
hashlib. - The first 5 characters of the hash are used to query the HIBP API, while the remaining part is checked against known breach data.
- Passwords are converted into SHA-1 hashes using
-
Output:
- For each password, the script outputs whether it's a common password or has been involved in a data breach.
- The results are formatted in a structured manner for clarity.
-
Error Handling:
- The script includes error handling for cases where the local file is missing or unreadable, providing informative messages to the user.
- Have I Been Pwned (HIBP) API: This API provides a list of millions of breached passwords, which are hashed using SHA-1 and stored in a database.
- A local common password list (
common_passwords.txt): This file contains a list of common passwords AI-generated that should be avoided.
Here's a breakdown of the code:
Importing libraries
The script starts by importing four libraries:
requests: for making HTTP requests to the HIBP APIhashlib: for hashing passwords using SHA-1sys: for accessing command-line argumentsimport time: for delay between requests, 1.5 seconds
The script defines four functions:
This function sends a GET request to the HIBP API with the first five characters of the password's SHA-1 hash as a query parameter (query_char). It returns the response object.
This function takes two parameters:
hashes: the response text from the HIBP API ( split into lines)hash_to_check: the remaining five characters of the password's SHA-1 hash
It iterates over the lines in hashes and checks if the second part (h) matches the hash_to_check. If a match is found, it returns the corresponding count. Otherwise, it returns 0.
This function takes a password as input and:
- Hashes the password using SHA-1
- Extracts the first five characters (
first5_char) and the remaining five characters (tail) - Calls
request_api_datawithfirst5_char - Calls
get_password_leaks_countwith the response from HIBP API andtail
The function returns the count of password breaches found.
This function checks if a password is in the local common password list (common-password.txt). If the file is not found or cannot be read, it skips the check and returns False.
Main function The main function takes command-line arguments as input (passwords to check). It:
- Prints a header with column names
- Iterates over each password:
- Checks if the password is in the local common password list
- If not, checks the HIBP API using
pwned_api_check
- Prints the result for each password with an extra newline at the end
Entry point
The script uses the if __name__ == '__main__': guard to ensure that the main function is only executed when the script is run directly (not imported as a module).
When run, the script expects one or more passwords as command-line arguments. Without arguments (passwords), it prints an error message and exits with a non-zero status code.
Example usage:
python pwned_passwords.py password123 commonpassThis would check if password123 and commonpass have been compromised in any data breaches or are in the local common password list.
############################################################################################################
It performs two main checks:
- Local common password check: Verifies if the password exists in a local file (
common_passwords.txt) containing a list of commonly used passwords. - HIBP API check: Uses the "Have I Been Pwned" (HIBP) API to check if the password has been exposed in known data breaches.
Here’s a breakdown of how your code works:
import requests
import hashlib
import sys
import timerequests: For making HTTP requests to the HIBP API.hashlib: For hashing passwords using SHA-1 (required by the HIBP API).sys: For handling command-line arguments and exiting with appropriate status codes.import time: for delay between requests, 1.5 seconds
API_REQUEST_DELAY = 1.5
- Added as a constant to specify the delay duration in seconds between requests.
- Sends a request to the HIBP API with the first 5 characters of the SHA-1 hash of the password.
- Returns the response containing a list of hash suffixes and their breach counts.
- Parses the API response to find if the full hash of the password exists in the breach data.
- Returns the number of times the password was found in breaches.
- Hashes the password using SHA-1 and splits it into the first 5 characters (
first5_char) and the rest (tail). time.sleep(API_REQUEST_DELAY), a delay is added before making the API request to avoid rate limiting.- Sends the first 5 characters to the API and checks if the
tailexists in the response. - Returns the breach count if found, or
0if not.
- Opens the common_passwords.txt file and loads its contents into a
setfor fast lookups. - Checks if the password exists in the set.
- Handles errors like missing or unreadable files gracefully by printing warnings and skipping the check.
- Accepts a list of passwords as command-line arguments.
- Prints a structured table header for the results.
- For each password:
- Strips whitespace to ensure clean input.
- Checks the local common password list:
- If found, marks the password as "Common password" and advises changing it.
- Checks the HIBP API:
- If found in breaches, marks the password as "Data breach" and displays the breach count.
- If neither check finds the password, marks it as "Secure password."
- Prints the results in a formatted table.
- Returns
0for success or1if no passwords were provided.
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))- Executes the
mainfunction with command-line arguments (excluding the script name). - Exits with the appropriate status code.
Command:
python passcheck.py password123 qwerty mysecurepasswordOutput:
Password | Status | Details
------------------------------------------------------------
password123 | Common password | Found in common_passwords list. Consider changing it!
qwerty | Common password | Found in common_passwords list. Consider changing it!
mysecurepassword | Non-breached password | Not found in breach or common_passwords list.
- Local and API-based checks: Combines local file checks with an online API for comprehensive password evaluation.
- Error handling: Gracefully handles missing files or API errors.
- User-friendly output: Displays results in a structured table format.
The script is designed to evaluate the security of passwords by checking against two sources: a local list of 1000 common passwords, AI-generated, and an external API, HIBP (Have I Been Pwned). The script is a useful tool for quickly assessing the security of passwords by combining checks against common passwords and known breach data. It's helpful for users who want to ensure their credentials are strong and have not been involved in past breaches.
