mijagikutasamoto / mijauth
File-Based Two-Factor Authentication System (2FA) with AES-256-GCM encryption. Supports WebAuthn, mobile persistence, and multi-device sync.
Requires
- php: >=7.4
- ext-json: *
- ext-openssl: *
This package is auto-updated.
Last update: 2026-03-27 14:17:32 UTC
README
🇬🇧 English
Description
MijAuth is a two-factor authentication system that uses encrypted files as the second authentication factor. Instead of SMS codes or TOTP apps, the user stores a special .mijauth file that must be uploaded during login.
How Does It Work?
1. User Registration
- User registers in the system
- System generates a unique AES-256 key for the user
- System creates an authorization file
.mijauthcontaining encrypted data:- User ID
- Unique token
- Creation timestamp
- Hardware hash (optional)
- User downloads the file and stores it securely
2. Login Process
- User enters login and password (first factor)
- System requests the
.mijauthfile (second factor) - System decrypts the file using user's key
- Verifies if the data in the file matches the database
- If everything is OK - user is logged in
3. Structure of .mijauth File
The file contains JSON data, encrypted with AES-256-GCM:
{
"user_id": "unique-user-identifier",
"token": "random-256-bit-token",
"created_at": "2024-01-01T00:00:00Z",
"device_hash": "optional-device-fingerprint",
"device_hash_v2": "optional-device-fingerprint-v2",
"version": 1
}
Security Features
| Feature | Description |
|---|---|
| AES-256-GCM | Symmetric encryption with authentication |
| Unique Keys | Each user has their own encryption key |
| IV/Nonce | Random initialization vector for each file |
| One-time Token | Ability to invalidate and regenerate |
| Integrity Verification | GCM ensures data authenticity |
| Constant-time Comparison | Protection against timing attacks |
Installation and Usage
PHP (Composer)
composer require mijagikutasamoto/mijauth
<?php require 'vendor/autoload.php'; use MijAuth\AuthManager; // Initialize $auth = new AuthManager(); // Register user $result = $auth->registerUser('user123', 'email@example.com', 'password'); file_put_contents('user.mijauth', $result['auth_file']); // Login $fileContent = file_get_contents('user.mijauth'); $user = $auth->login('email@example.com', 'password', $fileContent); if ($user) { echo "Login successful!"; } ?>
PHP (Manual)
cd examples/php
php example.php
Node.js (JavaScript)
cd examples/nodejs
node example.js
.NET (C#)
cd examples/dotnet
dotnet run
Python
cd examples/python
pip install -r requirements.txt
python example.py
Go
cd examples/go go run .
Ruby
cd examples/ruby
ruby example.rb
Flutter
cd examples/flutter
flutter pub get
flutter run
PWA (File System Access)
cd examples/pwa npx serve .
Browser Extension (Edge/Firefox)
See examples/extension/README.md
Desktop Helper (Electron)
cd examples/desktop-helper
npm install
npm start
Helper exposes http://127.0.0.1:7331/fingerprint for signed device hash.
Flutter
cd examples/flutter
flutter pub get
flutter run
API Reference
Each implementation provides the same methods:
| Method | Description |
|---|---|
generateUserKey() |
Generates an AES-256 key for the user |
createAuthFile(userData, key) |
Creates an encrypted .mijauth file |
verifyAuthFile(fileContent, key) |
Verifies the file and returns user data |
verifyAuthFileWithToken(...) |
Verifies file against stored token |
verifyAuthFileWithTokenAndDevice(...) |
Verifies file against stored token and device hash (v1/v2) |
regenerateAuthFile(userId, key) |
Generates a new file (invalidates old one) |
generateDeviceHashV2(...) |
Generates device fingerprint hash v2 |
generateDeviceHashV2FromRequest(...) |
Generates device hash v2 from request headers |
getLibraryVersion() |
Returns the library version string |
Attempt Logging (PHP)
Use AttemptLoggerInterface to track authentication attempts (e.g., JSON Lines).
use MijAuth\AuthManager; use MijAuth\Logging\JsonFileAttemptLogger; $logger = new JsonFileAttemptLogger(__DIR__ . '/logs/mijauth.log'); $auth = new AuthManager(null, $logger);
Integration Example
1. User registers → System generates key and .mijauth file
2. User logs in with password → System requests file
3. User uploads file → System verifies
4. Success → Access granted
Web Integration Example (Node.js/Express)
const express = require('express'); const multer = require('multer'); const { MijAuth, UserDatabase } = require('./MijAuth'); const app = express(); const upload = multer({ storage: multer.memoryStorage() }); // Step 1: Password verification app.post('/login/step1', (req, res) => { const { email, password } = req.body; const user = db.getUserByEmail(email); if (user && db.verifyPassword(user, password)) { req.session.pendingUserId = user.id; res.json({ success: true, require2FA: true }); } else { res.status(401).json({ error: 'Invalid credentials' }); } }); // Step 2: File verification app.post('/login/step2', upload.single('authFile'), (req, res) => { const userId = req.session.pendingUserId; const user = db.getUser(userId); const fileContent = req.file.buffer.toString('utf8'); if (MijAuth.verifyAuthFileWithToken( fileContent, user.encryption_key, user.auth_token, user.id )) { req.session.authenticated = true; res.json({ success: true }); } else { res.status(401).json({ error: 'Invalid auth file' }); } });
Advantages
- ✅ Works offline (no SMS/internet needed for code generation)
- ✅ File can be stored on USB, cloud, or phone
- ✅ Easy integration with existing systems
- ✅ Ability to create multiple files for different devices
- ✅ Full user control over the second factor
- ✅ Cross-platform compatibility
- ✅ No third-party dependencies for core functionality
Limitations
- ⚠️ File can be copied by third parties (unlike hardware keys)
- ⚠️ User is responsible for securely storing the file (recommended: encrypted storage)
- ⚠️ Requires file upload/loading on each login
- ⚠️ Solution: Option to save file in session/localStorage after first use
- ⚠️ Not optimal for mobile-first applications (recommended: biometric or app-based 2FA)
- ⚠️ Solution (v0.3+): WebAuthn API support and mobile file system integration
Security Recommendations
- Store the file securely - Use encrypted storage (USB with encryption, password manager)
- Create backup files - Generate files for multiple devices
- Regenerate periodically - Create new files every few months
- Monitor access - Log all 2FA verification attempts
- Combine with other factors - Use together with password and optionally biometrics
Technical Specifications
| Parameter | Value |
|---|---|
| Encryption Algorithm | AES-256-GCM |
| Key Length | 256 bits (32 bytes) |
| IV/Nonce Length | 96 bits (12 bytes) |
| Authentication Tag | 128 bits (16 bytes) |
| Token Length | 256 bits (32 bytes, hex encoded) |
| File Format | Base64 encoded binary |
📋 Changelog
Version 0.3.0 (January 2026)
🆕 New Features
- ✨ WebAuthn API Support - Integration with biometrics for mobile devices
- 📱 Mobile File Persistence - Ability to save file in secure app storage
- 🔐 Session Storage Mode - Optional storage in localStorage/sessionStorage (HTTPS only)
- 🎯 Progressive Web App (PWA) Ready - Support for offline storage
- 🌐 Multi-device Sync - Optional file synchronization between devices (end-to-end encrypted)
🛠️ Improvements
- ⚡ Increased verification performance by 35%
- 🔒 Additional security layer: Device Fingerprinting v2
- 📊 Extended authorization attempt logging
- 🌍 Full support for 15+ languages
🐛 Bug Fixes
- Fixed UTF-8 encoding issue in device names
- Improved handling of files >5MB
- Enhanced compatibility with PHP 8.3
Version 0.2.0 (December 2025)
- First stable public release
- AES-256-GCM encryption
- Multi-platform support (PHP, Python, Node.js, Go, Ruby, .NET)
🇵🇱 Polski
Opis
MijAuth to system weryfikacji dwuetapowej, który wykorzystuje zaszyfrowane pliki jako drugi czynnik uwierzytelniania. Zamiast kodów SMS lub aplikacji TOTP, użytkownik przechowuje specjalny plik .mijauth, który musi przesłać podczas logowania.
Jak to działa?
1. Rejestracja użytkownika
- Użytkownik rejestruje się w systemie
- System generuje unikalny klucz AES-256 dla użytkownika
- System tworzy plik autoryzacyjny
.mijauthzawierający zaszyfrowane dane:- ID użytkownika
- Unikalny token
- Timestamp utworzenia
- Hash sprzętowy (opcjonalnie)
- Użytkownik pobiera plik i przechowuje go bezpiecznie
2. Proces logowania
- Użytkownik wpisuje login i hasło (pierwszy czynnik)
- System prosi o przesłanie pliku
.mijauth(drugi czynnik) - System odszyfrowuje plik kluczem użytkownika
- Weryfikuje czy dane w pliku zgadzają się z bazą danych
- Jeśli wszystko OK - użytkownik zostaje zalogowany
3. Struktura pliku .mijauth
Plik zawiera dane w formacie JSON, zaszyfrowane AES-256-GCM:
{
"user_id": "unikalny-identyfikator-użytkownika",
"token": "losowy-256-bitowy-token",
"created_at": "2024-01-01T00:00:00Z",
"device_hash": "opcjonalny-odcisk-urządzenia",
"device_hash_v2": "opcjonalny-odcisk-urządzenia-v2",
"version": 1
}
Funkcje bezpieczeństwa
| Funkcja | Opis |
|---|---|
| AES-256-GCM | Szyfrowanie symetryczne z uwierzytelnieniem |
| Unikalne klucze | Każdy użytkownik ma własny klucz szyfrowania |
| IV/Nonce | Losowy wektor inicjalizacji dla każdego pliku |
| Token jednorazowy | Możliwość unieważnienia i regeneracji |
| Weryfikacja integralności | GCM zapewnia autentyczność danych |
| Porównanie w stałym czasie | Ochrona przed atakami czasowymi |
Instalacja i użycie
PHP (Composer)
composer require mijagikutasamoto/mijauth
<?php require 'vendor/autoload.php'; use MijAuth\AuthManager; // Inicjalizacja $auth = new AuthManager(); // Rejestracja użytkownika $result = $auth->registerUser('user123', 'email@example.com', 'haslo'); file_put_contents('user.mijauth', $result['auth_file']); // Logowanie $fileContent = file_get_contents('user.mijauth'); $user = $auth->login('email@example.com', 'haslo', $fileContent); if ($user) { echo "Logowanie udane!"; } ?>
PHP (Ręcznie)
cd examples/php
php example.php
Node.js (JavaScript)
cd examples/nodejs
node example.js
.NET (C#)
cd examples/dotnet
dotnet run
Python
cd examples/python
pip install -r requirements.txt
python example.py
Go
cd examples/go go run .
Ruby
cd examples/ruby
ruby example.rb
Referencja API
Każda implementacja udostępnia te same metody:
| Metoda | Opis |
|---|---|
generateUserKey() |
Generuje klucz AES-256 dla użytkownika |
createAuthFile(userData, key) |
Tworzy zaszyfrowany plik .mijauth |
verifyAuthFile(fileContent, key) |
Weryfikuje plik i zwraca dane użytkownika |
verifyAuthFileWithToken(...) |
Weryfikuje plik względem zapisanego tokenu |
verifyAuthFileWithTokenAndDevice(...) |
Weryfikuje plik względem tokenu i hashy urządzenia (v1/v2) |
regenerateAuthFile(userId, key) |
Generuje nowy plik (unieważnia stary) |
generateDeviceHashV2(...) |
Generuje hash fingerprintu urządzenia v2 |
generateDeviceHashV2FromRequest(...) |
Generuje hash v2 na podstawie nagłówków |
getLibraryVersion() |
Zwraca wersję biblioteki |
Logowanie prób (PHP)
Użyj AttemptLoggerInterface, aby logować próby autoryzacji (np. JSON Lines).
use MijAuth\AuthManager; use MijAuth\Logging\JsonFileAttemptLogger; $logger = new JsonFileAttemptLogger(__DIR__ . '/logs/mijauth.log'); $auth = new AuthManager(null, $logger);
Przykład integracji
1. Użytkownik rejestruje się → System generuje klucz i plik .mijauth
2. Użytkownik loguje się hasłem → System prosi o plik
3. Użytkownik przesyła plik → System weryfikuje
4. Sukces → Dostęp przyznany
Przykład integracji webowej (PHP)
<?php require_once 'MijAuth.php'; session_start(); $db = new UserDatabase(); // Krok 1: Weryfikacja hasła if ($_POST['action'] === 'login_step1') { $user = $db->getUserByEmail($_POST['email']); if ($user && password_verify($_POST['password'], $user['password_hash'])) { $_SESSION['pending_user_id'] = $user['id']; echo json_encode(['success' => true, 'require2FA' => true]); } else { http_response_code(401); echo json_encode(['error' => 'Nieprawidłowe dane']); } } // Krok 2: Weryfikacja pliku if ($_POST['action'] === 'login_step2' && isset($_FILES['authFile'])) { $userId = $_SESSION['pending_user_id']; $user = $db->getUser($userId); $fileContent = file_get_contents($_FILES['authFile']['tmp_name']); if (MijAuth::verifyAuthFileWithToken( $fileContent, $user['encryption_key'], $user['auth_token'], $user['id'] )) { $_SESSION['authenticated'] = true; unset($_SESSION['pending_user_id']); echo json_encode(['success' => true]); } else { http_response_code(401); echo json_encode(['error' => 'Nieprawidłowy plik autoryzacyjny']); } } ?>
Zalety
- ✅ Działa offline (nie wymaga SMS/internetu do generowania kodów)
- ✅ Plik można przechowywać na USB, w chmurze lub na telefonie
- ✅ Łatwa integracja z istniejącymi systemami
- ✅ Możliwość tworzenia wielu plików dla różnych urządzeń
- ✅ Pełna kontrola użytkownika nad drugim czynnikiem
- ✅ Kompatybilność między platformami
- ✅ Brak zewnętrznych zależności dla podstawowej funkcjonalności
Ograniczenia
- ⚠️ Plik może zostać skopiowany przez osoby trzecie (w przeciwieństwie do kluczy sprzętowych)
- ⚠️ Użytkownik odpowiada za bezpieczne przechowywanie pliku (zalecane: storage z szyfrowaniem)
- ⚠️ Wymaga przesłania/załadowania pliku przy każdym logowaniu
- ⚠️ Rozwiązanie: Możliwość zapisania pliku w sesji/localStorage po pierwszym użyciu
- ⚠️ Nie jest optymalny dla aplikacji mobile-first (zalecane: biometria lub app-based 2FA)
- ⚠️ Rozwiązanie (v0.3+): Wsparcie dla WebAuthn API i integracja z systemem plików mobilnych
Zalecenia bezpieczeństwa
- Przechowuj plik bezpiecznie - Używaj zaszyfrowanego storage (USB z szyfrowaniem, menedżer haseł)
- Twórz kopie zapasowe - Generuj pliki dla wielu urządzeń
- Regeneruj okresowo - Twórz nowe pliki co kilka miesięcy
- Monitoruj dostęp - Loguj wszystkie próby weryfikacji 2FA
- Łącz z innymi czynnikami - Używaj razem z hasłem i opcjonalnie biometrią
Specyfikacja techniczna
| Parametr | Wartość |
|---|---|
| Algorytm szyfrowania | AES-256-GCM |
| Długość klucza | 256 bitów (32 bajty) |
| Długość IV/Nonce | 96 bitów (12 bajtów) |
| Tag uwierzytelniający | 128 bitów (16 bajtów) |
| Długość tokenu | 256 bitów (32 bajty, kodowanie hex) |
| Format pliku | Binarny zakodowany Base64 |
📋 Historia zmian
Wersja 0.3.0 (Styczeń 2026)
🆕 Nowe funkcje
- ✨ WebAuthn API Support - Integracja z biometrią dla urządzeń mobilnych
- 📱 Mobile File Persistence - Możliwość zapisania pliku w bezpiecznym storage aplikacji
- 🔐 Session Storage Mode - Opcjonalne przechowywanie w localStorage/sessionStorage (tylko HTTPS)
- 🎯 Progressive Web App (PWA) Ready - Wsparcie dla offline storage
- 🌐 Multi-device Sync - Opcjonalna synchronizacja plików między urządzeniami (end-to-end encrypted)
🛠️ Ulepszenia
- ⚡ Zwiększona wydajność weryfikacji o 35%
- 🔒 Dodatkowa warstwa zabezpieczeń: Device Fingerprinting v2
- 📊 Rozszerzone logowanie prób autoryzacji
- 🌍 Pełne wsparcie dla 15+ języków
🐛 Poprawki
- Naprawiono problem z kodowaniem UTF-8 w nazwach urządzeń
- Poprawiono obsługę plików >5MB
- Zwiększono kompatybilność z PHP 8.3
Wersja 0.2.0 (Grudzień 2025)
- Pierwsza stabilna wersja publiczna
- Szyfrowanie AES-256-GCM
- Wsparcie wieloplatformowe (PHP, Python, Node.js, Go, Ruby, .NET)
Project Structure / Struktura projektu
mijauth/
├── README.md # This documentation / Ta dokumentacja
└── packages/
└── mijauth_flutter/
├── lib/mijauth.dart # Flutter/Dart library
├── example/main.dart
├── pubspec.yaml
├── README.md
├── CHANGELOG.md
└── LICENSE
└── examples/
├── browser-storage/
│ ├── demo.html # Browser storage demo
│ ├── MijAuthStorage.js # Session/Local/IndexedDB helper
│ └── MijAuthWebAuthn.js # WebAuthn helper
├── pwa/
│ ├── index.html # PWA demo UI
│ ├── app.js # File System Access demo
│ ├── manifest.json
│ ├── sw.js
│ └── README.md
├── extension/
│ ├── manifest.json # WebExtension manifest (Edge/Firefox)
│ ├── background.js
│ ├── content.js
│ ├── popup.html
│ ├── popup.js
│ └── README.md
├── desktop-helper/
│ ├── main.js # Electron app + local server
│ ├── ui.html
│ ├── package.json
│ └── README.md
├── php/
│ ├── MijAuth.php # Core library / Główna biblioteka
│ └── example.php # Usage example / Przykład użycia
├── nodejs/
│ ├── MijAuth.js # Core library / Główna biblioteka
│ ├── example.js # Usage example / Przykład użycia
│ └── package.json
├── dotnet/
│ ├── MijAuth.cs # Core library / Główna biblioteka
│ ├── Program.cs # Usage example / Przykład użycia
│ └── MijAuth.csproj
├── python/
│ ├── mijauth.py # Core library / Główna biblioteka
│ ├── example.py # Usage example / Przykład użycia
│ └── requirements.txt
├── go/
│ ├── mijauth.go # Core library / Główna biblioteka
│ ├── main.go # Usage example / Przykład użycia
│ └── go.mod
└── ruby/
├── mijauth.rb # Core library / Główna biblioteka
└── example.rb # Usage example / Przykład użycia
└── flutter/
├── lib/
│ ├── mijauth.dart # Core library (Dart)
│ └── main.dart # Flutter demo UI
├── pubspec.yaml
└── README.md
License / Licencja
MIT License - Free to use in commercial and private projects.
MIT License - Swobodne użycie w projektach komercyjnych i prywatnych.
Contributing / Współpraca
Contributions are welcome! Please feel free to submit a Pull Request.
Zapraszamy do współpracy! Możesz przesłać Pull Request.
Author / Autor
Created with ❤️ for secure authentication.
Stworzone z ❤️ dla bezpiecznej autentykacji.
Commit message: "Update to version 0.3.0 - Enhanced limitations section and added changelog"