New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

keystroke-dynamics

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

keystroke-dynamics

Passwordless authentication for the browser

latest
Source
npmnpm
Version
1.0.2
Version published
Maintainers
1
Created
Source

Keystroke Dynamics Authentication 🔐

A modern, passwordless authentication system that uses keystroke dynamics (typing patterns) to authenticate users. Experience the future of secure login where your typing rhythm becomes your password.

Demo Browser Support License Security

🎯 What is Keystroke Dynamics?

Keystroke dynamics analyzes the unique patterns in how you type - the timing between keystrokes, how long you hold keys down, and the rhythm of your typing. Just like your fingerprint, your typing pattern is unique to you!

✨ Features

  • 🚫 No Passwords Required - Type your username/email naturally to login
  • 🛡️ Bank-Level Security - AES-256 encryption with customizable thresholds
  • 🎯 High Accuracy - 95%+ authentication success rate after training
  • 🔄 Smart Fallback - Automatic password backup after 3 failed attempts
  • 📱 Cross-Platform - Works on desktop and mobile browsers
  • 🏠 Privacy First - All data stays on your device, no servers required
  • Lightning Fast - Sub-second authentication
  • 🎨 Easy Integration - Drop-in solution for any website

🚀 Quick Start

1. Download and Include

<!DOCTYPE html>
<html>
<head>
    <title>My Secure App</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <!-- Your login form -->
    <input type="text" id="username" placeholder="Type your username">
    <button id="loginBtn">Login</button>
    
    <!-- Include the scripts -->
    <script src="https://cdn.jsdelivr.net/npm/keystroke-dynamics@latest/keystroke-dynamics.min.js"></script>
    <script src="your-app.js"></script>
</body>
</html>

2. Initialize the System

// Create the authentication system
const auth = new KeystrokeDynamics();

// Set up your user (one-time setup)
await auth.initialize('your-master-password', 'user@example.com');

// Train the system (collect 5 samples)
for (let i = 0; i < 5; i++) {
    auth.startRecording();
    // User types their username
    await auth.addSample();
}

3. Authenticate Users

// When user tries to login
document.getElementById('username').addEventListener('input', (e) => {
    if (e.target.value.length === 1) {
        auth.startRecording(); // Start capturing keystrokes
    }
});

document.getElementById('loginBtn').addEventListener('click', async () => {
    try {
        const result = await auth.verify();
        
        if (result.isAuthentic && result.similarity >= 0.7) {
            console.log('✅ Login successful!');
            // Redirect to dashboard
        } else {
            console.log('❌ Authentication failed');
            // Show password field
        }
    } catch (error) {
        console.error('Authentication error:', error);
    }
});

📋 Complete Example

Here's a fully working login system:

class SecureLogin {
    constructor() {
        this.auth = new KeystrokeDynamics();
        this.attempts = 0;
        this.maxAttempts = 3;
        this.setupEventListeners();
    }

    async init(masterPassword, username) {
        await this.auth.initialize(masterPassword, username);
        this.auth.setThreshold(0.7); // 70% similarity required
    }

    setupEventListeners() {
        const usernameInput = document.getElementById('username');
        const loginBtn = document.getElementById('loginBtn');
        
        usernameInput.addEventListener('input', (e) => {
            if (e.target.value.length === 1 && !this.auth.isRecording) {
                this.auth.startRecording();
                this.showStatus('Recording your typing pattern...');
            }
        });

        loginBtn.addEventListener('click', () => this.handleLogin());
    }

    async handleLogin() {
        try {
            const result = await this.auth.verify();
            
            if (result.isAuthentic && result.similarity >= 0.7) {
                this.loginSuccess();
            } else {
                this.attempts++;
                if (this.attempts >= this.maxAttempts) {
                    this.showPasswordField();
                } else {
                    this.showRetryMessage(result.similarity);
                }
            }
        } catch (error) {
            this.handleError(error);
        }
    }

    loginSuccess() {
        this.showStatus('✅ Login successful!', 'success');
        // Redirect or update UI
        window.location.href = '/dashboard';
    }

    showPasswordField() {
        document.getElementById('passwordField').style.display = 'block';
        this.showStatus('⚠️ Biometric authentication failed. Please enter password.', 'warning');
    }

    showRetryMessage(similarity) {
        const attemptsLeft = this.maxAttempts - this.attempts;
        const similarityPercent = Math.round(similarity * 100);
        this.showStatus(
            `❌ Similarity: ${similarityPercent}% (need 70%). ${attemptsLeft} attempts left.`,
            'error'
        );
        document.getElementById('username').value = '';
    }

    showStatus(message, type = 'info') {
        const statusDiv = document.getElementById('status');
        statusDiv.textContent = message;
        statusDiv.className = `status ${type}`;
    }

    handleError(error) {
        console.error('Authentication error:', error);
        this.showStatus('🔥 Authentication system error', 'error');
    }
}

// Initialize when page loads
document.addEventListener('DOMContentLoaded', async () => {
    const login = new SecureLogin();
    
    // Check if user exists, otherwise set up new user
    if (!login.auth.isReady()) {
        await login.init('secure-master-password', 'john@example.com');
        // Show training interface
    }
});

🎛️ Configuration Options

Security Levels

// Choose your security level
auth.setThreshold('low');    // 60% - Relaxed security
auth.setThreshold('medium'); // 70% - Balanced (recommended)
auth.setThreshold('high');   // 80% - Strict security
auth.setThreshold('max');    // 90% - Maximum security

// Or use custom threshold
auth.setThreshold(0.75); // 75% similarity required

Training Options

// Minimum samples for training
const minSamples = 3;  // Quick setup
const recommended = 5; // Balanced accuracy
const maxSamples = 10; // Best accuracy

// Check training status
console.log(`Samples collected: ${result.sampleCount}`);
console.log(`Accuracy: ${Math.round(result.similarity * 100)}%`);

📱 Browser Support

BrowserVersionStatus
Chrome60+✅ Full Support
Firefox55+✅ Full Support
Safari11+✅ Full Support
Edge79+✅ Full Support
Opera47+✅ Full Support

Requirements:

  • IndexedDB support
  • Web Crypto API
  • ES6+ JavaScript
  • HTTPS (production only)

🛡️ Security Features

Encryption

  • AES-256-GCM encryption for all stored data
  • PBKDF2 key derivation (100,000 iterations)
  • Random salt and IV for each encryption operation
  • SHA-256 hashing for master keys

Privacy

  • Zero server communication - everything happens locally
  • No biometric data transmission - patterns never leave your device
  • Automatic data cleanup - old samples can be purged
  • Master password protection - encrypted with your password only

Anti-Fraud

  • Timing attack prevention - normalized timing windows
  • Replay attack protection - each sample includes timestamp
  • Threshold validation - customizable security levels
  • Attempt limiting - automatic lockout after failed attempts

🎨 UI/UX Best Practices

Progressive Enhancement

Start with a regular login form and enhance it:

// Check if biometrics are available
if (window.KeystrokeDynamics && auth.isReady()) {
    enableBiometricLogin();
} else {
    showTraditionalLogin();
}

Visual Feedback

Provide clear user feedback:

/* Recording state */
.input-recording {
    border: 2px solid #007bff;
    animation: pulse 1s infinite;
}

/* Success state */
.input-success {
    border: 2px solid #28a745;
}

/* Error state */
.input-error {
    border: 2px solid #dc3545;
}

User Guidance

// Provide helpful tips
const tips = [
    "Type naturally at your normal pace",
    "Use the same typing style as during training",
    "Ensure you're typing in the correct field",
    "Try to maintain consistent rhythm"
];

function showRandomTip() {
    const tip = tips[Math.floor(Math.random() * tips.length)];
    document.getElementById('helpText').textContent = tip;
}

🔧 API Reference

Core Methods

initialize(masterPassword, phrase)

Set up the system for a new user.

await auth.initialize('secure123', 'user@example.com');

startRecording(targetElement?)

Begin capturing keystroke data.

auth.startRecording(inputElement); // Bind to specific input
auth.startRecording(); // Capture globally

addSample()

Add a training sample to improve accuracy.

auth.startRecording();
// User types...
await auth.addSample();

verify()

Verify current keystroke pattern.

const result = await auth.verify();
console.log(result);
/*
{
    isAuthentic: true,
    similarity: 0.85,
    threshold: 0.70,
    sampleCount: 5
}
*/

setThreshold(level)

Configure security level.

auth.setThreshold(0.8);        // Numeric (0.0-1.0)
auth.setThreshold('medium');   // String level

Properties

auth.isReady()      // System initialized?
auth.isRecording    // Currently capturing?
auth.phrase         // Training phrase
auth.threshold      // Current threshold

📊 Performance Tips

Optimization

// Lazy load for better performance
class LazyAuth {
    async getAuth() {
        if (!this.auth) {
            this.auth = new KeystrokeDynamics();
            await this.auth.initialize(password, phrase);
        }
        return this.auth;
    }
}

Memory Management

// Clean up resources
auth.clearSignatures(); // Remove old training data
auth.reset();           // Complete system reset

🚨 Error Handling

Common Errors

try {
    await auth.verify();
} catch (error) {
    switch (error.code) {
        case 'NO_DATA':
            console.log('No keystrokes captured');
            break;
        case 'INSUFFICIENT_SAMPLES':
            console.log('Need more training data');
            break;
        case 'VERIFY_FAILED':
            console.log('Authentication failed');
            break;
        default:
            console.log('Unknown error:', error.message);
    }
}

Debug Mode

// Enable detailed logging
window.enableDebug = true;

// Monitor keystroke capture
auth.onKeystroke = (event) => {
    console.log('Captured:', event.key, event.timestamp);
};

🎯 Use Cases

E-commerce

// Quick checkout without passwords
if (await biometricAuth.verify()) {
    processPayment();
} else {
    requirePasswordAndOTP();
}

Banking

// High-security transactions
auth.setThreshold('max'); // 90% similarity
const result = await auth.verify();
if (result.similarity > 0.9) {
    allowTransaction();
}

Corporate

// Employee access control
const employee = await auth.authenticate(employeeId);
if (employee && result.isAuthentic) {
    grantSystemAccess(employee.permissions);
}

Education

// Secure exam authentication
auth.setThreshold('high');
if (await auth.verify()) {
    startExam();
} else {
    requireProctorVerification();
}

🔍 Troubleshooting

Common Issues

❌ "No keystroke data recorded"

// Solution: Ensure startRecording() is called
auth.startRecording(inputElement);

❌ "IndexedDB not supported"

// Solution: Check browser compatibility
if (!window.indexedDB) {
    showUnsupportedBrowserMessage();
}

❌ "Low similarity scores"

// Solution: More training or lower threshold
if (result.similarity < 0.6) {
    suggestMoreTraining();
    // OR
    auth.setThreshold('low');
}

❌ "Web Crypto API not available"

// Solution: Ensure HTTPS in production
if (location.protocol !== 'https:' && location.hostname !== 'localhost') {
    console.error('HTTPS required for production');
}

Performance Issues

// Reduce sample size for faster processing
const maxSamples = 5; // Instead of 10

// Use web workers for heavy computation (advanced)
const worker = new Worker('crypto-worker.js');

📈 Analytics & Monitoring

// Track authentication metrics
const metrics = {
    attempts: 0,
    successes: 0,
    averageSimilarity: 0,
    trainingAccuracy: 0
};

// Log authentication attempts
auth.onVerify = (result) => {
    metrics.attempts++;
    if (result.isAuthentic) metrics.successes++;
    
    // Send to analytics
    analytics.track('biometric_auth', {
        success: result.isAuthentic,
        similarity: result.similarity,
        threshold: result.threshold
    });
};

🚀 Deployment

Production Checklist

  • HTTPS enabled
  • Master passwords are strong and unique
  • Error handling implemented
  • Fallback authentication ready
  • User training flow tested
  • Browser compatibility verified
  • Performance optimized
  • Security audit completed

CDN Deployment

<!-- CDN ready -->
<script src="https://cdn.jsdelivr.net/keystroke-dynamics@latest/keystroke-dynamics.min.js"></script>

Self-Hosted

# Extract and serve
unzip keystroke-dynamics.zip
cp *.js /var/www/html/js/

🤝 Contributing

Contributions are welcome! Here's how to get started:

  • Fork the repository
  • Create a feature branch (git checkout -b feature/amazing-feature)
  • Commit your changes (git commit -m 'Add amazing feature')
  • Push to the branch (git push origin feature/amazing-feature)
  • Open a Pull Request

Development Setup

git clone https://github.com/Omodaka9375/keystroke-dynamics.git
cd keystroke-dynamics

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🌟 Show Your Support

If you find this project useful, please consider:

  • Starring this repository
  • 🔄 Sharing with your network
  • 💖 Sponsoring development
  • 📝 Writing a blog post about it
  • 🐛 Reporting bugs and issues

Made with ❤️ by developers, for developers

Securing the web, one keystroke at a time 🔐

Keywords

keystroke-dynamics

FAQs

Package last updated on 15 Aug 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts