3 min read

Desktop Personal Finance Tracker

A privacy-first desktop finance application built in Python and SQLite, featuring salted SHA-256 password hashing, automated brute-force lockout defense, categorized budgeting, and spending analytics.

  • Python
  • Tkinter
  • SQLite
  • Security
  • Data Management

1. Overview & Motivation

Most personal finance tools require users to store sensitive financial data on third-party cloud servers or pay recurring subscriptions. I built the Desktop Personal Finance Tracker to offer a local-first, privacy-respecting alternative that keeps financial records completely offline.

The application combines a lightweight desktop user interface with defensive authentication practices and structured relational storage—ensuring user data is safe, private, and accessible without an internet connection.


2. Key Highlights & Features

  • Privacy-First & Fully Offline: All financial data remains strictly on your local machine within a structured SQLite database. No telemetry, third-party trackers, or cloud sync required.
  • Defensive Security Model: Protects user credentials with cryptographically salted SHA-256 hashing and rate-limits login attempts to defend against brute-force attacks.
  • Structured Transaction Management: Quickly log, categorize, and filter income and expenses with automatic real-time balance calculations.
  • Interactive Spending Analytics: Visual summaries of spending patterns broken down by category, week, and month to highlight major expenditure drivers.
  • Zero Dependencies: Built entirely with standard library Python and native SQLite, ensuring seamless cross-platform execution on Windows, macOS, and Linux without complex setup.

3. Architecture & Data Flow

The application follows a clean modular structure separating user interface, business logic, security authentication, and database persistence:

[ User Input (Tkinter GUI) ]
              │
              ▼
[ Form Validation & Input Sanitization ]
              │
    ┌─────────┴─────────┐
    ▼                   ▼
[ Auth Manager ]    [ Transaction Engine ]
 (Salted SHA-256)    (Calculations & Rules)
    │                   │
    └─────────┬─────────┘
              ▼
    [ SQLite Data Layer ]
  (ACID-Compliant Local DB)

Core System Workflow:

  1. Authentication: Validates user credentials against stored salt and hash pairs. After 3 consecutive failed attempts, access is temporarily locked.
  2. Transaction Entry: User inputs amount, category, date, and description with strict type validation (preventing negative amounts or malformed dates).
  3. Database Execution: Uses parameterized queries to commit records safely, preventing SQL injection vulnerabilities.
  4. Dashboard Refresh: Dynamically aggregates current month expenditures and computes net savings for instant visual feedback.

4. Security Engineering

Salted SHA-256 Hashing

Storing passwords in plaintext or using unsalted hashes leaves credentials vulnerable to rainbow table attacks. Each user account generates a unique cryptographic salt via Python's secrets.token_hex() module. The salt is combined with the user's password before being hashed through SHA-256, creating a unique hash string stored securely in SQLite:

Stored Hash = SHA-256(Salt + Password)

Automated Brute-Force Lockout

To prevent automated credential guessing, the authentication controller maintains a running count of failed login attempts:

  • Attempts 1 to 3: Standard error notification with remaining retry counter.
  • Attempt 4 and above: Authentication is temporarily locked down with an active cooldown timer.

5. Technical Stack

Layer Technology Purpose
Programming Language Python 3.x Core application logic, mathematical calculations, and business rules
Desktop UI Tkinter / ttk Responsive, native desktop graphical interface
Database SQLite3 Local persistent storage with relational integrity
Cryptography hashlib & secrets Cryptographically secure salt generation and password hashing
Data Processing Python Standard Library Date parsing, data aggregation, and category filtering

6. Engineering Challenges & Lessons Learned

  • State Synchronization in Desktop GUIs: Ensuring the main Tkinter UI thread remained responsive during batch database operations required clean separation between database queries and UI render cycles.
  • Defensive Edge-Case Handling: Implemented thorough input validation routines to gracefully handle irregular edge cases, such as decimal formatting anomalies, date boundary parsing, and corrupted database recovery.
  • Designing for Maintainability: Modularizing authentication, database handlers, and UI views into distinct modules made testing and feature extensions straightforward.