import os import csv import time import urllib.parse import requests INPUT_FILE = "./addresses.txt" OUTPUT_FILE = "./resultats_hibp.csv" API_KEY = "API_KEY" USER_AGENT = "Python-HIBP-Bulk-Checker" BASE_URL = "https://haveibeenpwned.com/api/v3/breachedaccount/" def check_email(email, api_key): encoded_email = urllib.parse.quote(email.strip()) url = f"{BASE_URL}{encoded_email}?truncateResponse=true" headers = { "hibp-api-key": api_key, "user-agent": USER_AGENT } while True: try: response = requests.get(url, headers=headers) if response.status_code == 200: # Found breaches data = response.json() breach_names = [breach['Name'] for breach in data] return "Compromis (Pwned)", len(breach_names), "; ".join(breach_names) elif response.status_code == 404: # Didn't find anything, means no breach or email doesn't exists return "Sûr (Clean)", 0, "" # Exceptions (technicalities) elif response.status_code == 429: retry_after = int(response.headers.get("Retry-After", 2)) print(f" [!] Limite de requêtes atteinte. Pause forcée de {retry_after} secondes...") time.sleep(retry_after) continue elif response.status_code == 401: return "Erreur (Clé API invalide ou manquante)", 0, "" elif response.status_code == 403: return "Erreur (Accès interdit / User-Agent bloqué)", 0, "" else: return f"Erreur (Code HTTP {response.status_code})", 0, "" except requests.exceptions.RequestException as e: return f"Erreur de connexion ({str(e)})", 0, "" def main(): if not os.path.exists(INPUT_FILE): print(f"[-] Erreur : Le fichier '{INPUT_FILE}' est introuvable.") print(f"[*] Veuillez créer un fichier texte nommé '{INPUT_FILE}' à côté du script,") print("[*] et ajoutez-y une adresse email par ligne.") return if API_KEY == "VOTRE_CLE_API_ICI" or not API_KEY: print("[!] Attention : N'oubliez pas d'insérer votre clé API HaveIBeenPwned dans la variable 'API_KEY'.") print("[!] L'API v3 de HIBP nécessite obligatoirement une clé authentifiée (abonnement payant).") print("-" * 60) with open(INPUT_FILE, "r", encoding="utf-8") as f: emails = [line.strip() for line in f if line.strip()] if not emails: print(f"[-] Le fichier '{INPUT_FILE}' est vide. Aucune adresse à analyser.") return print(f"[*] Démarrage de l'analyse pour {len(emails)} adresse(s) email...") print(f"[*] Les résultats seront enregistrés dans '{OUTPUT_FILE}'.\n") with open(OUTPUT_FILE, "w", newline="", encoding="utf-8") as csvfile: writer = csv.writer(csvfile) writer.writerow(["Email", "Statut", "Nombre de Breches", "Liste des Breches"]) for index, email in enumerate(emails, 1): print(f"[{index}/{len(emails)}] Analyse de : {email} ...") status, count, breaches = check_email(email, API_KEY) writer.writerow([email, status, count, breaches]) if count > 0: # Has Been PWNED print(f" -> {status} ! Trouvé dans {count} brèche(s) : {breaches}") elif status == "Sûr (Clean)": # Hasn't been print(" -> Aucun problème détecté.") else: # Exception print(f" -> {status}") time.sleep(1.5) print(f"\n[+] Analyse terminée avec succès !") print(f"[+] Fichier de résultats généré : '{OUTPUT_FILE}'") if __name__ == "__main__": main()