fingerprint-web

0.0.1 • Public • Published

Web-Based Fingerprint

Version License Size

A lightweight, deterministic browser fingerprinting library that generates consistent device signatures without cookies or storage. Perfect for enhancing security, preventing fraud, or implementing robust user identification systems.

Developer

Table of Contents

Features

  • Forever FREE & Unlimited - No dependency, no server cost, runs on regular browser
  • Stable & Deterministic - Same fingerprint across page loads and sessions
  • Zero Dependencies - Only 2KB minified
  • Multiple Hash Formats - SHA-256, SHA-512, SHA-1, or custom length
  • Customizable Components - Enable/disable specific entropy sources
  • Multiple Output Formats - Hex, Base64, Integer, or Binary
  • Cross-Browser Compatible - Works in all modern browsers
  • Privacy-Friendly - No cookies, localStorage, or server components
  • Extensible Architecture - Add custom entropy sources

Installation

Using NPM/Yarn

# NPM
npm install fingerprint-web

# Yarn
yarn add fingerprint-web

Using CDN

<!-- Direct script include -->
<script src="https://unpkg.com/fingerprint-web@latest/dist/fingerprint.min.js"></script>

<!-- Now available globally as Fingerprint -->
<script>
  const fingerprinter = new Fingerprint();
  fingerprinter.get().then(hash => {
    console.log("Browser fingerprint:", hash);
  });
</script>

Direct Download

You can also download the library directly from the GitHub repository and include it in your project:

<script src="path/to/fingerprint.min.js"></script>

Quick Start

import Fingerprint from 'fingerprint-web';

// Create fingerprinter and get device signature
const fingerprinter = new Fingerprint();
fingerprinter.get().then(fingerprint => {
    console.log('Fingerprint:', fingerprint);
    // e.g. "3f4e591c86c9c5f734fc4b54d5322549bf85ec34b4c2f36310490b3e187b733d"
});

How It Works

Web-Based Fingerprint generates deterministic device signatures by combining multiple stable browser and hardware characteristics:

  1. Data Collection: The library collects various entropy sources that remain consistent between browser sessions:

    • Hardware identifiers (screen resolution, color depth, CPU cores)
    • Browser configuration (user agent, language, plugins)
    • Rendering capabilities (canvas, WebGL, color gamut)
    • System settings (timezone, fonts, preferences)
  2. Component Processing: Each data point is normalized to ensure consistency:

    • Canvas rendering uses controlled drawing parameters
    • WebGL details include vendor and renderer information
    • Font detection identifies system fonts without accessing the file system
    • Plugin details are sorted and normalized
  3. Weighting System: More reliable components can be given higher weight

  4. Cryptographic Hashing: All collected data points are combined and processed through cryptographic hashing (SHA-256 by default)

  5. Format Conversion: The resulting hash can be represented in various formats (hex, base64, integer)

The fingerprint remains consistent across browser sessions because it's based on stable device and browser characteristics rather than stored data.

Detailed Fingerprinting Process

  1. Browser Information Collection:

    • User agent string is captured exactly as provided by the browser
    • Language preferences are normalized to ensure consistent format
    • Do Not Track setting is captured as a boolean value
  2. Hardware Information Collection:

    • Screen dimensions and color depth are captured in a consistent format
    • CPU core count and device memory are included when available
    • Touch point capability helps distinguish mobile from desktop devices
  3. Advanced Fingerprinting Techniques:

    • Canvas fingerprinting draws specific shapes and text with controlled parameters
    • WebGL fingerprinting captures graphics hardware details
    • Font availability detection uses width comparison techniques
    • Audio context processing creates a unique audio signature (optional)
  4. Data Processing:

    • All components are joined using a configurable separator
    • The combined string is hashed using a cryptographic algorithm
    • The resulting hash can be truncated or formatted as needed

Complete Customization Guide

The library offers extensive customization options for different use cases:

Component Selection

Choose which entropy sources to include:

const fingerprinter = new Fingerprint({
  components: {
    // Browser basics
    userAgent: true,
    language: true,
    doNotTrack: true,
    
    // Hardware identifiers
    screen: true,
    hardware: true,
    touchPoints: true,
    
    // Advanced sources
    canvas: true,
    webGL: true,
    colorGamut: true,
    
    // Additional sources
    plugins: true,
    fonts: true,
    timezone: true,
    
    // Optional (more volatile)
    audio: false
  }
});

Hash Algorithm & Length

Choose cryptographic algorithm and result length:

// SHA-512 with custom length output
const fingerprinter = new Fingerprint({
  hashAlgorithm: 'SHA-512', // 'SHA-1', 'SHA-256', 'SHA-384', 'SHA-512'
  hashLength: 32           // First 32 characters only (default: 0 = full length)
});

Component Weighting

Give more weight to more reliable components:

const fingerprinter = new Fingerprint({
  weights: {
    // Higher values = more influence on final fingerprint
    canvas: 3,     // Canvas has 3x normal weight
    webGL: 2,      // WebGL has 2x normal weight
    userAgent: 2,  // User agent has 2x normal weight
    // All other components have default weight of 1
  }
});

Custom Entropy Sources

Add your own data sources:

const fingerprinter = new Fingerprint({
  customComponents: [
    // Check for specific browser features
    function() {
      return {
        speechSynthesis: 'speechSynthesis' in window,
        bluetooth: 'bluetooth' in navigator,
        serviceWorker: 'serviceWorker' in navigator
      };
    },
    
    // Connection information
    function() {
      const connection = navigator.connection || 
                        navigator.mozConnection || 
                        navigator.webkitConnection;
      return connection ? connection.effectiveType : 'unknown';
    }
  ]
});

Runtime Configuration Override

Change options at runtime without creating new instances:

const fingerprinter = new Fingerprint();

// First get standard fingerprint
fingerprinter.get().then(standardHash => {
  console.log('Standard fingerprint:', standardHash);
  
  // Then get a shorter SHA-1 fingerprint with the same instance
  return fingerprinter.get({
    hashAlgorithm: 'SHA-1',
    hashLength: 16
  });
}).then(shortHash => {
  console.log('Short SHA-1 fingerprint:', shortHash);
});

Excluding Volatile Components

For maximum stability across sessions:

const stableFingerprinter = new Fingerprint({
  // Exclude all potentially volatile components
  excludeVolatile: true,
  
  // Disable specific volatile components individually
  components: {
    audio: false,
    plugins: false
  }
});

Font Detection Customization

Control how fonts are detected:

const fingerprinter = new Fingerprint({
  // Enable or disable font detection entirely
  enableFonts: true,
  
  // Font detection is included in components
  components: {
    fonts: true
  }
});

Custom Separator

Change how components are joined:

const fingerprinter = new Fingerprint({
  // Use a different separator between components
  separator: ':::' // Default is '||'
});

Common Use Cases

1. Minimal Stable Fingerprint

// Only use the most stable components for maximum consistency
const minimalFingerprint = new Fingerprint({
    components: {
        userAgent: true,
        screen: true, 
        language: true,
        canvas: true,
        webGL: true,
        // Disable less stable components
        fonts: false,
        plugins: false,
        timezone: false,
        colorGamut: false,
        touchPoints: false,
        hardware: false,
        doNotTrack: false
    },
    hashLength: 32 // Shorter output
});

2. Different Output Formats

// Get fingerprint in different formats
fingerprinter.get().then(hash => {
    // Different representations of the same fingerprint
    console.log('Hex:', hash);
    console.log('Base64:', fingerprinter.formatHash(hash, 'base64'));
    console.log('Integer:', fingerprinter.formatHash(hash, 'int'));
    console.log('Binary:', fingerprinter.formatHash(hash, 'binary').substring(0, 64) + '...');
});

3. Maximum Entropy

// Maximum entropy configuration
const enhancedFingerprint = new Fingerprint({
    // Use stronger hash algorithm
    hashAlgorithm: 'SHA-512',
    
    // Include all components including audio
    components: { 
        /* ... all components enabled ... */ 
        audio: true 
    },
    
    // Include less stable components
    excludeVolatile: false,
    
    // Prioritize the most reliable components
    weights: {
        canvas: 3,  // Canvas has 3x normal influence
        webGL: 2    // WebGL has 2x normal influence
    }
});

4. Real-World Example: Fraud Prevention

// Create a fingerprint instance
const fingerprinter = new Fingerprint({
  // Balance between stability and uniqueness
  components: {
    userAgent: true,
    screen: true,
    language: true,
    timezone: true,
    canvas: true,
    webGL: true,
    plugins: true,
    fonts: true,
    // Disable less stable components
    audio: false
  }
});

// When user logs in or makes a purchase
async function verifyUser(userId, transaction) {
  // Get current device fingerprint
  const deviceFingerprint = await fingerprinter.get();
  
  // Check against known devices for this user
  const isKnownDevice = await checkDeviceDatabase(userId, deviceFingerprint);
  
  if (!isKnownDevice && transaction.amount > 1000) {
    // Require additional verification for large transactions on new devices
    return requestAdditionalVerification(userId, transaction);
  } else {
    // Proceed with transaction
    return processTransaction(userId, transaction, deviceFingerprint);
  }
}

5. Browser Bot Detection

// Create a high-entropy fingerprinter
const botDetectionFingerprinter = new Fingerprint({
  components: {
    userAgent: true,
    language: true,
    timezone: true,
    screen: true,
    canvas: true,
    webGL: true,
    fonts: true,
    plugins: true,
    audio: true
  },
  excludeVolatile: false,
  customComponents: [
    // Add bot detection heuristics
    function() {
      return {
        // Check for inconsistencies typical in bots
        navigatorPrototype: Object.getOwnPropertyNames(Navigator.prototype).length,
        windowKeys: Object.keys(window).length,
        // Automation detection
        webdriver: navigator.webdriver,
        automation: window.navigator.webdriver || 
                   window.document.documentElement.getAttribute("webdriver") ||
                   window.callPhantom || 
                   window._phantom
      };
    }
  ]
});

// Check if current client is likely a bot
async function detectBot() {
  const fingerprint = await botDetectionFingerprinter.get();
  const rawData = await botDetectionFingerprinter.getRawData();
  
  // Analyze fingerprint and raw data for bot indicators
  const botScore = calculateBotScore(fingerprint, rawData);
  
  return {
    isBot: botScore > 0.7,
    confidence: botScore,
    fingerprint: fingerprint
  };
}

API Reference

Constructor Options

new Fingerprint({
    // Core settings
    hashAlgorithm: 'SHA-256', // 'SHA-1', 'SHA-256', 'SHA-384', 'SHA-512'
    hashLength: 0,            // 0 = full length, or specify character count
    enableFonts: true,        // Include font detection
    excludeVolatile: true,    // Exclude less stable components
    
    // Enable/disable specific components
    components: {
        userAgent: true,      // User agent string
        language: true,       // Browser language
        screen: true,         // Screen dimensions and color depth
        timezone: true,       // System timezone
        touchPoints: true,    // Touch point capability
        hardware: true,       // CPU cores and device memory
        doNotTrack: true,     // Do Not Track setting
        canvas: true,         // Canvas fingerprinting
        webGL: true,          // WebGL vendor and renderer
        colorGamut: true,     // Color gamut capabilities
        plugins: true,        // Browser plugins
        fonts: true,          // System fonts
        audio: false          // Audio processing (off by default)
    },
    
    // Component weight factors (higher = more influence)
    weights: { 
        userAgent: 1, 
        language: 1, 
        screen: 1, 
        timezone: 1, 
        touchPoints: 1, 
        hardware: 1, 
        doNotTrack: 1, 
        canvas: 1, 
        webGL: 1, 
        colorGamut: 1, 
        plugins: 1, 
        fonts: 1, 
        audio: 1 
    },
    
    // Custom entropy sources
    customComponents: [],
    
    // Data separator
    separator: '||'
});

Core Methods

Method Description Return Type Example
get([overrideOptions]) Generates fingerprint hash Promise<string> fingerprinter.get()
getRawData() Returns raw component data Promise<Array> fingerprinter.getRawData()
formatHash(hash, format) Converts hash format string|number fingerprinter.formatHash(hash, 'base64')
static createComponent(fn) Creates reusable component Function Fingerprint.createComponent(fn)

Method Details

get([overrideOptions])

Generates and returns the fingerprint hash.

Parameters:

  • overrideOptions (Object, optional): Runtime options that override constructor options

Returns: Promise<string> - The fingerprint hash

Example:

// Basic usage
fingerprinter.get().then(hash => console.log(hash));

// With runtime options
fingerprinter.get({
  hashAlgorithm: 'SHA-1',
  hashLength: 16
}).then(hash => console.log(hash));

getRawData()

Returns the raw fingerprint data before hashing.

Returns: Promise<Array> - Array of collected data points

Example:

fingerprinter.getRawData().then(data => {
  console.log('Raw fingerprint components:', data);
  
  // Analyze components
  data.forEach((component, index) => {
    console.log(`Component ${index}:`, component);
  });
});

formatHash(hash, format)

Converts the fingerprint hash to various output formats.

Parameters:

  • hash (String): The fingerprint hash to convert
  • format (String, optional): Output format (default: 'hex')
    • 'hex': Hexadecimal format (default)
    • 'base64': Base64 encoding
    • 'int': Integer representation (first 53 bits)
    • 'binary': Binary string (0s and 1s)

Returns: The formatted hash (String or Number)

Example:

fingerprinter.get().then(hash => {
  console.log('Hex:', hash);
  console.log('Base64:', fingerprinter.formatHash(hash, 'base64'));
  console.log('Integer:', fingerprinter.formatHash(hash, 'int'));
  console.log('Binary:', fingerprinter.formatHash(hash, 'binary'));
});

static createComponent(fn)

Creates a reusable component function that can be added to customComponents.

Parameters:

  • fn (Function): Function that returns a fingerprint component value

Returns: Properly formatted component function

Example:

const screenOrientationComponent = Fingerprint.createComponent(function() {
  return screen.orientation ? screen.orientation.type : 'orientation_unsupported';
});

const fingerprinter = new Fingerprint({
  customComponents: [screenOrientationComponent]
});

Output Formats

// Available formats
fingerprinter.formatHash(hash, 'hex');     // Default hexadecimal format
fingerprinter.formatHash(hash, 'base64');  // Base64 encoding
fingerprinter.formatHash(hash, 'int');     // Integer representation (first 53 bits)
fingerprinter.formatHash(hash, 'binary');  // Binary string (0s and 1s)

Custom Components

Add your own entropy sources:

const fingerprinter = new Fingerprint({
    customComponents: [
        // Check for browser features
        function() {
            return {
                speechSynthesis: 'speechSynthesis' in window,
                bluetooth: 'bluetooth' in navigator,
                serviceWorker: 'serviceWorker' in navigator
            };
        },
        
        // Any function returning string or object
        function() {
            return navigator.connection?.effectiveType || 'unknown';
        }
    ]
});

// Creating reusable components
const mediaDeviceComponent = Fingerprint.createComponent(async function() {
    if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
        return 'media_api_unsupported';
    }
    
    try {
        const devices = await navigator.mediaDevices.enumerateDevices();
        const counts = {
            audioinput: 0,
            audiooutput: 0,
            videoinput: 0
        };
        
        devices.forEach(device => {
            if (counts[device.kind] !== undefined) {
                counts[device.kind]++;
            }
        });
        
        return `media_${counts.audioinput}_${counts.audiooutput}_${counts.videoinput}`;
    } catch (e) {
        return 'media_error';
    }
});

// Use the reusable component
const enhancedFingerprinter = new Fingerprint({
    customComponents: [mediaDeviceComponent]
});

Advanced Custom Component Examples

LocalStorage Detection

const storageComponent = Fingerprint.createComponent(function() {
  const storageTypes = {
    localStorage: false,
    sessionStorage: false,
    indexedDB: false
  };
  
  try {
    // Test localStorage
    localStorage.setItem('test', 'test');
    localStorage.removeItem('test');
    storageTypes.localStorage = true;
  } catch (e) {}
  
  try {
    // Test sessionStorage
    sessionStorage.setItem('test', 'test');
    sessionStorage.removeItem('test');
    storageTypes.sessionStorage = true;
  } catch (e) {}
  
  try {
    // Test indexedDB
    storageTypes.indexedDB = !!window.indexedDB;
  } catch (e) {}
  
  return storageTypes;
});

Font Metrics

const fontMetricsComponent = Fingerprint.createComponent(function() {
  const testString = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  const testElement = document.createElement('span');
  testElement.style.position = 'absolute';
  testElement.style.left = '-9999px';
  testElement.style.fontSize = '72px';
  testElement.textContent = testString;
  
  document.body.appendChild(testElement);
  
  // Test with different fonts
  const fonts = ['monospace', 'sans-serif', 'serif'];
  const metrics = {};
  
  fonts.forEach(font => {
    testElement.style.fontFamily = font;
    metrics[font] = {
      width: testElement.offsetWidth,
      height: testElement.offsetHeight
    };
  });
  
  document.body.removeChild(testElement);
  return metrics;
});

Entropy Sources

The library combines these stable browser/hardware characteristics:

Core Browser Data

  • User Agent: Complete browser and OS identification string
  • Language: Browser language preferences
  • Do Not Track: User's tracking preference setting

Hardware Information

  • Screen Properties: Resolution, color depth, pixel ratio
  • CPU & Memory: Core count and device memory (when available)
  • Touch Capability: Maximum touch points supported
  • Timezone: User's geographical timezone

Graphics Fingerprinting

  • Canvas Rendering: How the browser renders specific shapes and text
  • WebGL Information: Graphics card vendor and renderer details
  • Color Gamut: Display's color reproduction capabilities

Software Enumeration

  • Browser Plugins: Installed browser extensions and plugins
  • Font Availability: System fonts detection
  • Audio Processing: How the device processes audio signals (optional)

Custom Sources

  • Any additional entropy sources added through custom components

Browser Support

Browser Version Support Level
Chrome 49+ ✅ Full
Firefox 52+ ✅ Full
Safari 11+ ✅ Full
Edge 79+ ✅ Full
Opera 36+ ✅ Full
IE 11 ⚠️ Basic (no audio fingerprinting)
Chrome for Android 49+ ✅ Full
Safari iOS 11+ ✅ Full
Samsung Internet 5+ ✅ Full
UC Browser 12+ ✅ Full

Browser Compatibility Notes

  • Internet Explorer: Limited support. WebGL and some canvas features may be unreliable.
  • Safari: Full support, but some font detection features may behave differently.
  • Mobile Browsers: Full support on modern mobile browsers.
  • Privacy Modes: Fingerprinting works in incognito/private browsing modes.

📝 License

MIT License - feel free to use and modify as needed.


Developed by Jafran Hasan, Sr Software Developer at WPPOOL.

Package Sidebar

Install

npm i fingerprint-web

Weekly Downloads

4

Version

0.0.1

License

MIT

Unpacked Size

59.2 kB

Total Files

6

Last publish

Collaborators

  • iamjafran