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:
- Authentication: Validates user credentials against stored salt and hash pairs. After 3 consecutive failed attempts, access is temporarily locked.
- Transaction Entry: User inputs amount, category, date, and description with strict type validation (preventing negative amounts or malformed dates).
- Database Execution: Uses parameterized queries to commit records safely, preventing SQL injection vulnerabilities.
- 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.
GitHub Link
https://github.com/srhmk/finance-tracker