A cryptographic authentication system that implements passwordless authentication using ElGamal digital signatures and a challenge-response protocol. This project demonstrates how to build a secure authentication system without transmitting passwords during login.
This C# application provides a complete authentication framework where users authenticate by proving possession of a private key through digital signatures. Instead of sending passwords, users sign server-generated challenges, providing strong cryptographic authentication.
- ElGamal Digital Signatures: Full implementation of ElGamal signature generation and verification
- Challenge-Response Protocol: Time-limited challenges prevent replay attacks
- Passwordless Authentication: No password transmission during login
- Session Management: Secure session token generation and validation
- Configurable Security: Adjustable key sizes and challenge TTL
- Thread-Safe Operations: All storage and authentication operations are thread-safe
- Key Serialization: Support for exporting/importing public keys in JSON format
-
ElGamal Cryptography (
ElGamalKeyGeneration.cs,ElGamalSignature.cs)- Prime number generation using Miller-Rabin primality test
- ElGamal key pair generation (public/private keys)
- Message signing and signature verification
- SHA-256 hashing for message digest
-
Authentication Service (
AuthenticationService.cs)- User registration with public key storage
- Challenge generation with expiration
- Signature verification and authentication
- Session token management
-
Client Library (
AuthenticationClient.cs)- Simplified API for registration and login
- Automatic key pair management
- Challenge signing automation
-
Storage Layer (
InMemoryUserStorage.cs)- In-memory user storage (can be extended to database)
- Thread-safe user operations
- .NET 9.0 SDK or later
- Windows, Linux, or macOS
- Clone the repository:
git clone <repository-url>
cd auth_elgamal- Restore dependencies:
dotnet restore- Build the project:
dotnet build- Run the demo:
dotnet run --project auth_elgamalusing auth_elgamal;
using auth_elgamal.Client;
using auth_elgamal.Services;
using auth_elgamal.Storage;
// Setup
var storage = new InMemoryUserStorage();
var settings = new AuthSettings
{
ChallengeTtl = TimeSpan.FromMinutes(2),
DefaultKeySizeBits = 512
};
var service = new AuthenticationService(storage, settings);
var client = new AuthenticationClient(service);
// Register a new user
var register = client.Register("alice", "password123", 512);
Console.WriteLine($"Register: {register.Success} - {register.Message}");
// Login
var login = client.Login("alice");
Console.WriteLine($"Login: {login.Success} - {login.Message}");
if (login.Success)
{
var token = client.GetSessionToken();
Console.WriteLine($"Session token: {token}");
// Validate session
bool isValid = service.IsValidSession(token!);
string? username = service.GetUsernameFromSession(token!);
Console.WriteLine($"Session valid: {isValid}, User: {username}");
}var settings = new AuthSettings
{
ChallengeTtl = TimeSpan.FromMinutes(5), // Challenge expiration time
DefaultKeySizeBits = 2048 // Key size in bits (512, 1024, 2048, etc.)
};
var service = new AuthenticationService(storage, settings, new ConsoleAuthLogger());Client Server
| |
|-- Generate ElGamal Key Pair --|
| |
|-- Register(username, -->|
| password, publicKey) |
| |-- Store user with:
| | - Username
| | - Password hash (SHA-256)
| | - Public key
|<-- Registration Response -----|
| |
Client Server
| |
|-- Request Challenge(username) -->|
| |-- Generate random challenge
| |-- Store challenge with TTL
|<-- Challenge (message, id) ---|
| |
|-- Sign challenge with |
| private key |
| |
|-- Authenticate(username, -->|
| challengeId, signature) |
| |-- Verify signature using
| | stored public key
| |-- Check challenge expiration
|<-- Auth Response + |
| Session Token -------------|
| |
Client Server
| |
|-- Validate Session(token) ---->|
| |-- Check token exists
| |-- Return username
|<-- Session Status + |
| Username ------------------|
| |
- Cryptographic Authentication: Uses ElGamal digital signatures (asymmetric cryptography)
- Challenge-Response Protocol: Prevents replay attacks with time-limited challenges
- No Password Transmission: Passwords are only used during registration, never sent during login
- Secure Hashing: SHA-256 for password hashing and message digest
- Thread Safety: All operations are protected with locks
- Configurable TTL: Challenge expiration prevents stale authentication attempts
auth_elgamal/
โโโ Client/
โ โโโ AuthenticationClient.cs # High-level client API
โโโ Models/
โ โโโ AuthModels.cs # Authentication request/response models
โ โโโ RegistrationModels.cs # Registration models
โ โโโ User.cs # User entity
โ โโโ ErrorCodes.cs # Error code enumerations
โโโ Services/
โ โโโ AuthenticationService.cs # Core authentication logic
โ โโโ AuthSettings.cs # Configuration settings
โ โโโ Logging.cs # Logging interface
โโโ Storage/
โ โโโ IUserStorage.cs # Storage interface
โ โโโ InMemoryUserStorage.cs # In-memory implementation
โโโ ElGamalKeyGeneration.cs # Key pair generation
โโโ ElGamalSignature.cs # Signing and verification
โโโ KeySerialization.cs # Key export/import utilities
โโโ Program.cs # Demo application
The implementation follows the standard ElGamal signature algorithm:
-
Key Generation:
- Generate large prime
p - Find generator
gof the multiplicative group - Choose private key
xrandomly - Compute public key
y = g^x mod p
- Generate large prime
-
Signing:
- Hash message to get
h - Choose random
kcoprime top-1 - Compute
r = g^k mod p - Compute
s = (h - x*r) * k^(-1) mod (p-1) - Signature is
(r, s)
- Hash message to get
-
Verification:
- Hash message to get
h - Verify:
g^h โก y^r * r^s (mod p)
- Hash message to get
- 512 bits: Fast, suitable for development/testing
- 1024 bits: Moderate security
- 2048 bits: Recommended for production (slower key generation)
The project includes a demo in Program.cs that demonstrates:
- User registration
- Challenge generation
- Authentication flow
- Session management
Run the demo:
dotnet run --project auth_elgamal- This is an educational project demonstrating cryptographic authentication
- The in-memory storage is for demonstration; production systems should use persistent storage
- Key generation can be slow for large key sizes (2048+ bits)
- The current implementation uses a fixed generator (g=2) for simplicity
- Database-backed user storage
- Key rotation support
- Multi-factor authentication
- API endpoints (REST/GraphQL)
- Key recovery mechanisms
- Rate limiting for challenges
- Audit logging
This project is for educational purposes as part of an information security course.
Note: This implementation is for educational demonstration. For production use, consider using established cryptographic libraries and security best practices.