#!/usr/bin/env bash # Enable strict error management set -o errexit set -o errtrace set -o pipefail # ============================================================================== # Comprehensive Passphrase Audit Function # ============================================================================== audit_passphrase() { local raw_password="$1" if [[ -z "$raw_password" ]]; then echo "[ERROR] No passphrase provided for validation." >&2 exit 2 fi # -------------------------------------------------------------------------- # GATE 1: Minimum Length Verification (35+ Characters) # -------------------------------------------------------------------------- local pass_len="${#raw_password}" if [ "$pass_len" -lt 35 ]; then echo "❌ REJECTED: Passphrase is too short ($pass_len characters). Minimum length required is 35." exit 1 fi echo " [PASS] Length verification satisfied ($pass_len characters)." # -------------------------------------------------------------------------- # GATE 2: Local Dictionary Check (cracklib-check) # -------------------------------------------------------------------------- # cracklib-check reads from stdin and outputs 'password: status' # If secure, the status string reads "OK" if ! command -v cracklib-check &> /dev/null; then echo "[WARN] cracklib-check binary not found. Skipping dictionary audit." >&2 else local cracklib_result cracklib_result=$(echo "$raw_password" | cracklib-check | cut -d':' -f2 | xargs) if [[ "$cracklib_result" != "OK" ]]; then echo "❌ REJECTED by cracklib-check: $cracklib_result" exit 1 fi echo " [PASS] Local dictionary and structural complexity audit clear." fi # -------------------------------------------------------------------------- # GATE 3: Remote Anonymized Leak Check (HIBP API via k-Anonymity) # -------------------------------------------------------------------------- local full_hash full_hash=$(echo -n "$raw_password" | openssl dgst -sha1 | awk '{print toupper($2)}') local prefix="${full_hash:0:5}" local suffix="${full_hash:5}" local api_url="https://api.pwnedpasswords.com/range/$prefix" local response if ! response=$(curl -s -H "User-Agent: Bash-Passphrase-Audit-Script" "$api_url"); then echo "[FATAL] Failed to communicate with HIBP API." >&2 exit 3 fi local match match=$(echo "$response" | grep -i "^$suffix:") if [[ -n "$match" ]]; then local pwn_count pwn_count=$(echo "$match" | cut -d':' -f2 | tr -d $'\r') echo "❌ VULNERABLE: This passphrase has appeared in $pwn_count known public breaches." exit 1 else echo "✅ SUCCESS: Passphrase meets all local criteria and was not found in HIBP records." return 0 fi } # ============================================================================== # Execution Example # ============================================================================== echo "=== System Passphrase Security Enforcer ===" read -r -s -p "Enter a new secure passphrase (35+ chars): " user_input echo "" # Run the complete pipeline audit_passphrase "$user_input" exit_status=$? # Instantly wipe raw secret text from memory space unset user_input exit "$exit_status"