Privacy Tools Guide

Regularly auditing your password vault helps maintain strong security hygiene. Weak passwords, duplicates across accounts, and credential reuse create vulnerabilities that attackers exploit. This guide covers practical methods for auditing password vaults using command-line tools and scripts, designed for developers and power users who want programmatic control over their security posture.

Understanding Password Vault Auditing

Password managers store credentials in encrypted vaults, but they cannot automatically detect when you use weak or reused passwords. A weak password lacks entropy—complexity that makes brute-force attacks impractical. Duplicate passwords mean a single breach compromises multiple accounts. Auditing your vault periodically surfaces these issues so you can remediate them before attackers exploit them.

Most password managers provide built-in security dashboards. However, these tools often lack customization, export capabilities, or integration with automation workflows. Using CLI tools and scripts gives you deeper insight and the ability to build custom auditing pipelines.

Exporting Your Vault for Analysis

Before auditing, you need to export your vault data. Most password managers support encrypted exports that you can process locally. The exact method depends on your password manager, but the general approach involves authenticating and requesting a structured export.

For 1Password, use the CLI to export items in JSON format:

op item list --format json > vault_export.json

For Bitwarden, the CLI provides export functionality:

bw list items --pretty > vault_export.json

For KeePass, you can export to CSV using the KeePassXC GUI or command-line tools like keepassx-cli:

keepassx-cli info database.kdbx

Handle exported data carefully. These files contain sensitive credentials in plaintext. Process them in an ephemeral environment, delete them immediately after auditing, and never commit them to version control.

Detecting Weak Passwords

Weak password detection requires analyzing entropy and checking against known weak patterns. Several approaches exist: using dedicated tools, calculating entropy mathematically, or comparing against wordlists.

Using zxcvbn for Entropy Analysis

The zxcvbn library (originally developed by Dropbox) provides password strength estimation. It detects patterns, dictionary words, and common substitutions rather than simply counting character types.

Install the JavaScript version for command-line use:

npm install -g zxcvbn

Then analyze individual passwords:

echo "mysecretpassword" | zxcvbn

The output includes a score from 0 to 4, feedback on weaknesses, and estimated crack times. Integrate this into your auditing script:

import json
import subprocess

def check_password_strength(password):
    result = subprocess.run(
        ['zxcvbn', password],
        capture_output=True,
        text=True
    )
    return json.loads(result.stdout)

with open('vault_export.json') as f:
    vault = json.load(f)

weak_passwords = []
for item in vault:
    password = item.get('password', '')
    result = check_password_strength(password)
    if result['score'] < 3:
        weak_passwords.append({
            'title': item.get('title'),
            'score': result['score'],
            'feedback': result['feedback']['warning']
        })

print(json.dumps(weak_passwords, indent=2))

Entropy Calculation

Calculate entropy directly using Python for faster processing without external dependencies:

import math
import json
import re

def calculate_entropy(password):
    if not password:
        return 0
    charset_size = 0
    if re.search(r'[a-z]', password):
        charset_size += 26
    if re.search(r'[A-Z]', password):
        charset_size += 26
    if re.search(r'[0-9]', password):
        charset_size += 10
    if re.search(r'[^a-zA-Z0-9]', password):
        charset_size += 32

    entropy = len(password) * math.log2(charset_size) if charset_size > 0 else 0
    return round(entropy, 2)

# Entropy thresholds: below 40 bits is weak, above 60 is strong
ENTROPY_THRESHOLD = 40

with open('vault_export.json') as f:
    vault = json.load(f)

weak = [item for item in vault
        if calculate_entropy(item.get('password', '')) < ENTROPY_THRESHOLD]

print(f"Found {len(weak)} passwords below {ENTROPY_THRESHOLD} bits entropy")

Finding Duplicate and Reused Passwords

Duplicate detection is straightforward: group passwords by their hash or value and identify groups with more than one entry.

import json
from collections import defaultdict

with open('vault_export.json') as f:
    vault = json.load(f)

password_groups = defaultdict(list)
for item in vault:
    password = item.get('password', '')
    if password:
        password_groups[password].append(item.get('title', 'Unknown'))

duplicates = {pwd: titles for pwd, titles in password_groups.items()
              if len(titles) > 1}

print(f"Found {len(duplicates)} passwords used across multiple accounts:")
for password, titles in duplicates.items():
    print(f"\nPassword used in {len(titles)} accounts:")
    for title in titles:
        print(f"  - {title}")

This script identifies every password appearing more than once. For each duplicate, review whether sharing a password across accounts is necessary or whether you should generate unique passwords for each service.

Automating the Audit Pipeline

Build a complete auditing script that combines all checks into a single report:

#!/usr/bin/env python3
import json
import math
import re
import subprocess
from collections import defaultdict

def calculate_entropy(password):
    if not password:
        return 0
    charset_size = 0
    if re.search(r'[a-z]', password):
        charset_size += 26
    if re.search(r'[A-Z]', password):
        charset_size += 32
    if re.search(r'[0-9]', password):
        charset_size += 10
    if re.search(r'[^a-zA-Z0-9]', password):
        charset_size += 32
    entropy = len(password) * math.log2(charset_size)
    return round(entropy, 2)

def analyze_vault(vault_file):
    with open(vault_file) as f:
        vault = json.load(f)

    results = {
        'total_entries': len(vault),
        'weak_passwords': [],
        'reused_passwords': [],
        'short_passwords': []
    }

    password_groups = defaultdict(list)

    for item in vault:
        title = item.get('title', 'Unknown')
        password = item.get('password', '')

        if not password:
            continue

        # Track for duplicate detection
        password_groups[password].append(title)

        # Check entropy
        entropy = calculate_entropy(password)
        if entropy < 40:
            results['weak_passwords'].append({
                'title': title,
                'entropy': entropy
            })

        # Check length
        if len(password) < 12:
            results['short_passwords'].append({
                'title': title,
                'length': len(password)
            })

    # Find duplicates
    for password, titles in password_groups.items():
        if len(titles) > 1:
            results['reused_passwords'].append({
                'password': password[:8] + '...',
                'count': len(titles),
                'accounts': titles
            })

    return results

if __name__ == '__main__':
    results = analyze_vault('vault_export.json')

    print("=== Password Vault Audit Results ===\n")
    print(f"Total entries analyzed: {results['total_entries']}\n")

    print(f"Weak passwords (below 40 bits entropy): {len(results['weak_passwords'])}")
    for item in results['weak_passwords'][:5]:
        print(f"  - {item['title']}: {item['entropy']} bits")

    print(f"\nShort passwords (below 12 characters): {len(results['short_passwords'])}")
    for item in results['short_passwords'][:5]:
        print(f"  - {item['title']}: {item['length']} chars")

    print(f"\nReused passwords: {len(results['reused_passwords'])}")
    for item in results['reused_passwords'][:5]:
        print(f"  - Used in {item['count']} accounts: {', '.join(item['accounts'])}")

Run this script against your exported vault to generate a report. Schedule regular runs to track improvements over time.

Interpreting Results and Taking Action

After auditing, prioritize remediation based on risk. Accounts with reused passwords tied to high-value services—email, banking, or code repositories—require immediate attention. Generate new passwords using your password manager’s built-in generator, targeting at least 16 characters with a mix of character types.

For weak passwords, either strengthen them if the service allows or switch to a passkey if supported. Passkeys eliminate password reuse concerns entirely by using cryptographic key pairs instead of shared secrets.

Document your audit findings if working within an organization. Track remediation progress and set recurring audit schedules—monthly for high-security environments, quarterly for personal use.

Securing the Audit Process

Never store vault exports permanently. Create them in a temporary directory, process them, then delete immediately:

cd /tmp
cp ~/vault_export.json .
python3 audit.py vault_export.json
rm vault_export.json

Consider using a dedicated machine or container for auditing to isolate the process from your daily workflow. Disable network access during processing if possible to prevent accidental exfiltration.

Built by theluckystrike — More at zovo.one