Password Tools với Python

Xây dựng password generator, checker, và các công cụ bảo mật mật khẩu với Python.

Password Security

Passwords yếu là một trong những lỗ hổng phổ biến nhất. Hãy xây dựng các tools để tạo và kiểm tra passwords.

Password Generator

import secrets
import string

def generate_password(
    length: int = 16,
    uppercase: bool = True,
    lowercase: bool = True,
    digits: bool = True,
    special: bool = True
) -> str:
    """Generate a secure random password."""
    
    characters = ""
    
    if uppercase:
        characters += string.ascii_uppercase
    if lowercase:
        characters += string.ascii_lowercase
    if digits:
        characters += string.digits
    if special:
        characters += string.punctuation
    
    if not characters:
        raise ValueError("At least one character type must be selected")
    
    # Use secrets for cryptographically secure randomness
    password = ''.join(secrets.choice(characters) for _ in range(length))
    
    return password

# Tạo passwords
print(generate_password(16))  # Full random
print(generate_password(12, special=False))  # No special chars
print(generate_password(20, uppercase=False, lowercase=False))  # Only digits + special

Passphrase Generator

import secrets

WORDLIST = [
    "apple", "banana", "cherry", "dragon", "elephant",
    "falcon", "guitar", "horizon", "igloo", "jungle",
    "knight", "lemon", "mountain", "nebula", "ocean",
    "phoenix", "quantum", "rainbow", "silver", "thunder",
    "umbrella", "volcano", "whisper", "xenon", "yellow", "zenith"
]

def generate_passphrase(
    word_count: int = 4,
    separator: str = "-",
    capitalize: bool = True
) -> str:
    """Generate a memorable passphrase."""
    
    words = [secrets.choice(WORDLIST) for _ in range(word_count)]
    
    if capitalize:
        words = [word.capitalize() for word in words]
    
    return separator.join(words)

# Examples
print(generate_passphrase())  # Thunder-Ocean-Knight-Rainbow
print(generate_passphrase(5, "_"))  # apple_dragon_falcon_igloo_nebula
print(generate_passphrase(3, "", False))  # oceanmountainzenith

Password Strength Checker

import re
from enum import Enum

class PasswordStrength(Enum):
    VERY_WEAK = 0
    WEAK = 1
    MEDIUM = 2
    STRONG = 3
    VERY_STRONG = 4

def check_password_strength(password: str) -> dict:
    """Check password strength and return score with feedback."""
    
    score = 0
    feedback = []
    
    # Length checks
    length = len(password)
    if length < 8:
        feedback.append("Password too short (minimum 8 characters)")
    elif length >= 16:
        score += 2
    elif length >= 12:
        score += 1
    
    # Character variety
    has_lower = bool(re.search(r'[a-z]', password))
    has_upper = bool(re.search(r'[A-Z]', password))
    has_digit = bool(re.search(r'\d', password))
    has_special = bool(re.search(r'[!@#$%^&*(),.?":{}|<>]', password))
    
    if has_lower:
        score += 1
    else:
        feedback.append("Add lowercase letters")
    
    if has_upper:
        score += 1
    else:
        feedback.append("Add uppercase letters")
    
    if has_digit:
        score += 1
    else:
        feedback.append("Add numbers")
    
    if has_special:
        score += 2
    else:
        feedback.append("Add special characters")
    
    # Common patterns (bad)
    common_patterns = [
        r'123', r'abc', r'qwerty', r'password',
        r'(.)\1{2,}',  # Repeated characters
    ]
    
    for pattern in common_patterns:
        if re.search(pattern, password.lower()):
            score -= 1
            feedback.append("Avoid common patterns")
            break
    
    # Determine strength
    if score <= 1:
        strength = PasswordStrength.VERY_WEAK
    elif score <= 3:
        strength = PasswordStrength.WEAK
    elif score <= 5:
        strength = PasswordStrength.MEDIUM
    elif score <= 7:
        strength = PasswordStrength.STRONG
    else:
        strength = PasswordStrength.VERY_STRONG
    
    return {
        "password": password,
        "score": score,
        "strength": strength.name,
        "feedback": feedback
    }

# Test
result = check_password_strength("MyP@ssw0rd123!")
print(f"Strength: {result['strength']}")
print(f"Score: {result['score']}")
for tip in result['feedback']:
    print(f"  - {tip}")

Password Hash Cracker (Educational)

⚠️ Warning: Chỉ sử dụng cho mục đích học tập với hashes của bạn!

import hashlib
from typing import Optional

def crack_md5(hash_value: str, wordlist_path: str) -> Optional[str]:
    """
    Dictionary attack on MD5 hash.
    
    Args:
        hash_value: Target MD5 hash
        wordlist_path: Path to wordlist file
    
    Returns:
        Cracked password or None
    """
    
    hash_value = hash_value.lower()
    
    with open(wordlist_path, "r", encoding="utf-8", errors="ignore") as f:
        for line in f:
            word = line.strip()
            word_hash = hashlib.md5(word.encode()).hexdigest()
            
            if word_hash == hash_value:
                return word
    
    return None

def crack_with_rules(hash_value: str, wordlist: list) -> Optional[str]:
    """Apply common rules to wordlist for cracking."""
    
    hash_value = hash_value.lower()
    
    for word in wordlist:
        # Try variations
        variations = [
            word,
            word.capitalize(),
            word.upper(),
            word + "123",
            word + "!",
            word + "1",
            word.replace("a", "@"),
            word.replace("e", "3"),
            word.replace("o", "0"),
        ]
        
        for variant in variations:
            variant_hash = hashlib.md5(variant.encode()).hexdigest()
            if variant_hash == hash_value:
                return variant
    
    return None

# Usage
target_hash = "5f4dcc3b5aa765d61d8327deb882cf99"  # "password"
wordlist = ["admin", "password", "123456", "qwerty"]
result = crack_with_rules(target_hash, wordlist)
print(f"Cracked: {result}")

Brute Force Generator

import itertools
import string
from typing import Generator

def brute_force_generator(
    charset: str = string.ascii_lowercase,
    min_length: int = 1,
    max_length: int = 4
) -> Generator[str, None, None]:
    """Generate all possible combinations."""
    
    for length in range(min_length, max_length + 1):
        for combo in itertools.product(charset, repeat=length):
            yield ''.join(combo)

# Warning: This grows exponentially!
# 26^4 = 456,976 combinations for 4 lowercase letters

# Example: Generate and count (don't actually run for large lengths!)
count = 0
for password in brute_force_generator(max_length=3):
    count += 1
    if count <= 5:
        print(password)

print(f"Total: {count} combinations")

Password Manager (Simple)

import json
import getpass
from cryptography.fernet import Fernet
from pathlib import Path

class SimplePasswordManager:
    def __init__(self, data_file: str = "passwords.enc"):
        self.data_file = Path(data_file)
        self.key_file = Path("manager.key")
        self.passwords = {}
        
    def setup(self):
        """Generate encryption key on first run."""
        if not self.key_file.exists():
            key = Fernet.generate_key()
            self.key_file.write_bytes(key)
            self.save()
            print("Password manager initialized!")
        else:
            self.load()
    
    def _get_cipher(self) -> Fernet:
        key = self.key_file.read_bytes()
        return Fernet(key)
    
    def save(self):
        """Save passwords to encrypted file."""
        cipher = self._get_cipher()
        data = json.dumps(self.passwords).encode()
        encrypted = cipher.encrypt(data)
        self.data_file.write_bytes(encrypted)
    
    def load(self):
        """Load passwords from encrypted file."""
        if self.data_file.exists():
            cipher = self._get_cipher()
            encrypted = self.data_file.read_bytes()
            data = cipher.decrypt(encrypted)
            self.passwords = json.loads(data.decode())
    
    def add(self, service: str, username: str, password: str):
        """Add a new password."""
        self.passwords[service] = {
            "username": username,
            "password": password
        }
        self.save()
        print(f"Added password for {service}")
    
    def get(self, service: str) -> dict | None:
        """Get password for a service."""
        return self.passwords.get(service)
    
    def list_services(self) -> list:
        """List all saved services."""
        return list(self.passwords.keys())
    
    def delete(self, service: str):
        """Delete a password."""
        if service in self.passwords:
            del self.passwords[service]
            self.save()
            print(f"Deleted {service}")

# Usage
if __name__ == "__main__":
    pm = SimplePasswordManager()
    pm.setup()
    
    # Add password
    pm.add("github", "myuser", generate_password(16))
    
    # Get password
    creds = pm.get("github")
    if creds:
        print(f"Username: {creds['username']}")
        print(f"Password: {creds['password']}")
    
    # List all
    print(f"Services: {pm.list_services()}")

CLI Password Tool

#!/usr/bin/env python3
"""
Password utility CLI tool
"""

import argparse
import secrets
import string

def generate(args):
    chars = ""
    if args.lowercase:
        chars += string.ascii_lowercase
    if args.uppercase:
        chars += string.ascii_uppercase
    if args.digits:
        chars += string.digits
    if args.special:
        chars += string.punctuation
    
    if not chars:
        chars = string.ascii_letters + string.digits
    
    password = ''.join(secrets.choice(chars) for _ in range(args.length))
    print(password)

def main():
    parser = argparse.ArgumentParser(description="Password Tools")
    subparsers = parser.add_subparsers(dest="command")
    
    # Generate command
    gen_parser = subparsers.add_parser("generate", help="Generate password")
    gen_parser.add_argument("-l", "--length", type=int, default=16)
    gen_parser.add_argument("--lowercase", action="store_true", default=True)
    gen_parser.add_argument("--uppercase", action="store_true", default=True)
    gen_parser.add_argument("--digits", action="store_true", default=True)
    gen_parser.add_argument("--special", action="store_true", default=True)
    
    args = parser.parse_args()
    
    if args.command == "generate":
        generate(args)

if __name__ == "__main__":
    main()

Bước tiếp theo

Tiếp theo:

  • Packet Sniffer: Phân tích network traffic với Scapy

⚠️ Legal Notice: Chỉ crack passwords mà bạn có quyền! Không bao giờ sử dụng tools này cho mục đích bất hợp pháp.