File-Based Two-Factor Authentication System (2FA) with AES-256-GCM encryption. Supports WebAuthn, mobile persistence, and multi-device sync.

Maintainers

Package info

github.com/MijagiKutasamoto/mijauth

pkg:composer/mijagikutasamoto/mijauth

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-01-27 13:56 UTC

This package is auto-updated.

Last update: 2026-03-27 14:17:32 UTC


README

🇵🇱 Polski | 🇬🇧 English

🇬🇧 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 .mijauth containing encrypted data:
    • User ID
    • Unique token
    • Creation timestamp
    • Hardware hash (optional)
  • User downloads the file and stores it securely

2. Login Process

  1. User enters login and password (first factor)
  2. System requests the .mijauth file (second factor)
  3. System decrypts the file using user's key
  4. Verifies if the data in the file matches the database
  5. 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

  1. Store the file securely - Use encrypted storage (USB with encryption, password manager)
  2. Create backup files - Generate files for multiple devices
  3. Regenerate periodically - Create new files every few months
  4. Monitor access - Log all 2FA verification attempts
  5. 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 .mijauth zawierają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

  1. Użytkownik wpisuje login i hasło (pierwszy czynnik)
  2. System prosi o przesłanie pliku .mijauth (drugi czynnik)
  3. System odszyfrowuje plik kluczem użytkownika
  4. Weryfikuje czy dane w pliku zgadzają się z bazą danych
  5. 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

  1. Przechowuj plik bezpiecznie - Używaj zaszyfrowanego storage (USB z szyfrowaniem, menedżer haseł)
  2. Twórz kopie zapasowe - Generuj pliki dla wielu urządzeń
  3. Regeneruj okresowo - Twórz nowe pliki co kilka miesięcy
  4. Monitoruj dostęp - Loguj wszystkie próby weryfikacji 2FA
  5. Łą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"