npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@gibme/eapol

v22.0.0

Published

A comprehensive, low-level EAPOL (Extensible Authentication Protocol over LAN) Key Frame parser for Wi-Fi security protocols. Parses and validates EAPOL-Key frames used in WPA/WPA2/WPA3 4-way handshakes, group key handshakes, and Fast Transition (802.11r)

Downloads

23

Readme

@gibme/eapol

A comprehensive, low-level EAPOL (Extensible Authentication Protocol over LAN) Key Frame parser for Wi-Fi security protocols.

Parses and validates EAPOL-Key frames used in WPA/WPA2/WPA3 4-way handshakes, group key handshakes, and Fast Transition (802.11r) operations. Supports RSN/WPA IE parsing, all KDE types (GTK, IGTK, PMKID, etc.), and all standard cipher suites and AKM methods.

Parser-only implementation - does not perform cryptographic operations.

Requirements

  • Node.js >= 22

Installation

npm install @gibme/eapol

or

yarn add @gibme/eapol

Quick Start

import { Frame, EAPOL } from '@gibme/eapol';

// Parse from hex string
const frame = Frame.from('0203005f02...', 'hex');

// Parse from buffer
const frame = Frame.from(buffer);

// Identify the handshake message
console.log(`Message ${frame.messageNumber} of ${frame.handshakeType} handshake`);

// Validate the frame
const result = frame.validate();
if (!result.valid) {
    console.error('Validation errors:', result.errors);
}

Features

Frame Parsing

  • Parse complete EAPOL-Key frames from buffers or hex strings
  • Automatic frame detection — scans up to 512 bytes past 802.11/LLC headers to locate the EAPOL header
  • Supports EAPOL versions 1, 2, and 3 (802.1X-2001/2004/2010)
  • Extracts all key descriptor fields (nonces, MIC, replay counter, IVs, RSC, etc.)
  • Parses Key Information flags with full bit-field decoding

Security Protocol Support

| Protocol | Standard | Description | |---|---|---| | WPA/TKIP | IEEE 802.11i | Legacy WPA with Microsoft OUI (00:50:F2:01) | | WPA2/WPA3 | IEEE 802.11i/ac/ax | RSN Information Element (IE 0x30) parsing | | Fast Transition | IEEE 802.11r | Full FT-IE and Mobility Domain parsing | | PMF | IEEE 802.11w | Management Frame Protection with IGTK support | | FILS | IEEE 802.11ai | Fast Initial Link Setup support |

Key Data Encapsulation (KDE) Parsing

All standard KDE types are recognized and parsed:

  • GTK - Group Temporal Key (key ID, Tx flag, key material)
  • IGTK - Integrity Group Temporal Key with IPN (802.11w PMF)
  • PMKID - Pairwise Master Key Identifier (16 bytes)
  • MAC Address - TDLS peer identification
  • SMK - Station-to-Station Master Key (TDLS)
  • Nonce - Additional 32-byte nonce
  • Lifetime - Key lifetime in seconds
  • Error - Handshake error codes
  • Key ID - Generic key identifier
  • Multiband GTK / Key ID - Multi-band operation support

Cipher Suites

Complete constants for all IEEE 802.11 cipher suites:

| Constant | Value | Usage | |---|---|---| | CCMP_128 | 0x04 | WPA2/WPA3 standard | | GCMP_128 | 0x08 | WPA3 | | GCMP_256 | 0x09 | WPA3 192-bit | | CCMP_256 | 0x0a | WPA3 192-bit | | TKIP | 0x02 | Legacy WPA | | WEP40 / WEP_104 | 0x01 / 0x05 | Legacy (deprecated) | | BIP_CMAC_128 | 0x06 | PMF | | BIP_GMAC_128 / BIP_GMAC_256 | 0x0b / 0x0c | PMF | | BIP_CMAC_256 | 0x0d | PMF |

Available via EAPOL.PairwiseCipherSuite, EAPOL.GroupCipherSuite, and EAPOL.ManagementFrameProtectionSuite.

AKM Suites

All standard Authentication and Key Management methods:

| Constant | Value | Usage | |---|---|---| | PSK | 0x02 | WPA2-Personal | | EAP | 0x01 | WPA2-Enterprise | | SAE | 0x08 | WPA3-Personal | | OWE | 0x12 | Opportunistic Wireless Encryption | | FT_PSK / FT_SAE | 0x04 / 0x09 | Fast Transition variants | | EAP_SUITE_B_192 | 0x0c | WPA3-Enterprise 192-bit | | FILS_SHA256 / FILS_SHA384 | 0x0e / 0x0f | Fast Initial Link Setup | | SAE_EXT_KEY / FT_SAE_EXT_KEY | 0x18 / 0x19 | SAE with Extended Key | | PASN | 0x13 | Pre-Association Security Negotiation |

Available via EAPOL.AkmSuite.

Frame Validation

Comprehensive validation including:

  • EAPOL version and descriptor type compatibility
  • Key Information flag consistency per IEEE 802.11 spec
  • Message-specific requirements (Messages 1-4 of the 4-way handshake)
  • Replay counter validation
  • RSN/WPA IE structure integrity (version, cipher counts, AKM counts)
  • KDE structure validation (IGTK IPN length, MAC address length, PMKID length, nonce length)
  • Nonce and MIC presence requirements
  • Pairwise key length checks
  • Encrypted key data flag consistency

Handshake Message Detection

Automatic identification of 4-way handshake messages based on flag combinations:

| Message | Direction | Key Flags | |---|---|---| | Message 1 | AP -> STA | hasAck, no hasMic, no hasInstall | | Message 2 | STA -> AP | hasMic, no hasAck, no isSecure | | Message 3 | AP -> STA | hasAck, hasInstall, hasMic | | Message 4 | STA -> AP | hasMic, isSecure, no hasAck |

Also detects group key handshake messages.

Usage Examples

Identify Handshake Messages

import { Frame } from '@gibme/eapol';

const frame = Frame.from(buffer);

if (frame.isMessage1) {
    console.log('Message 1: AP -> STA (ANonce)');
    console.log('ANonce:', frame.keyNonce.toString('hex'));
}

if (frame.isMessage2) {
    console.log('Message 2: STA -> AP (SNonce, RSN IE)');
    console.log('SNonce:', frame.keyNonce.toString('hex'));
    console.log('RSN:', frame.rsn);
}

if (frame.isMessage3) {
    console.log('Message 3: AP -> STA (ANonce, GTK, Install)');
    console.log('GTK Key ID:', frame.gtk?.keyId);
    console.log('GTK:', frame.gtk?.gtk.toString('hex'));
}

if (frame.isMessage4) {
    console.log('Message 4: STA -> AP (Confirmation)');
}

Extract Security Information

const frame = Frame.from(buffer);

// RSN Information Element (WPA2/WPA3)
if (frame.rsn) {
    console.log('Version:', frame.rsn.version);
    console.log('Group Cipher:', frame.rsn.groupCipher.toString('hex'));
    console.log('Pairwise Ciphers:', frame.rsn.pairwiseCipherSuites.length);
    console.log('AKM Suites:', frame.rsn.akmSuites.length);
    console.log('MFP Required:', frame.rsn.capabilities.mfpRequired);
    console.log('MFP Capable:', frame.rsn.capabilities.mfpCapable);
    console.log('PMKIDs:', frame.rsn.pmkIds.length);
}

// Legacy WPA Information Element
if (frame.wpa) {
    console.log('WPA Version:', frame.wpa.version);
    console.log('Group Cipher:', frame.wpa.groupCipher.toString('hex'));
}

// Fast Transition (802.11r)
if (frame.ft) {
    console.log('Mobility Domain ID:', frame.mdid.toString('hex'));
    console.log('R0KH-ID:', frame.ft.r0KHId?.toString('hex'));
    console.log('R1KH-ID:', frame.ft.r1KHId?.toString('hex'));
}

Extract Keys

const frame = Frame.from(buffer);

// Group Temporal Key
if (frame.gtk) {
    console.log('GTK Key ID:', frame.gtk.keyId);
    console.log('GTK Tx Flag:', frame.gtk.txFlag);
    console.log('GTK:', frame.gtk.gtk.toString('hex'));
}

// Integrity Group Temporal Key (PMF)
if (frame.igtk) {
    console.log('IGTK Key ID:', frame.igtk.keyId);
    console.log('IGTK IPN:', frame.igtk.ipn.toString('hex'));
    console.log('IGTK:', frame.igtk.igtk.toString('hex'));
}

// PMKID (for fast roaming)
if (frame.pmkid) {
    console.log('PMKID:', frame.pmkid.pmkid.toString('hex'));
}

Compare Cipher Suites

import { Frame, EAPOL } from '@gibme/eapol';

const frame = Frame.from(buffer);

if (frame.rsn) {
    const supportsCCMP = frame.rsn.pairwiseCipherSuites.some(
        suite => suite.equals(EAPOL.PairwiseCipherSuite.CCMP_128)
    );

    const supportsSAE = frame.rsn.akmSuites.some(
        suite => suite.equals(EAPOL.AkmSuite.SAE)
    );

    console.log('Supports CCMP-128:', supportsCCMP);
    console.log('Supports WPA3-SAE:', supportsSAE);
}

Validate a Frame

const frame = Frame.from(buffer);
const validation = frame.validate();

if (!validation.valid) {
    console.error('Frame validation failed:');
    validation.errors.forEach(err => console.error(`  - ${err}`));
} else {
    console.log('Frame is valid');
    console.log('Key Descriptor Version valid:', frame.isValidKeyDescriptorVersion());
}

MIC Verification Support

const frame = Frame.from(buffer);

// Get the frame with MIC field zeroed for external MIC calculation
const zeroedFrame = frame.zeroedFrame;

// The MIC algorithm depends on the Key Descriptor Version
switch (frame.keyVersion) {
    case EAPOL.KeyVersion.HMAC_MD5_RC4:
        // HMAC-MD5 (WPA/TKIP)
        break;
    case EAPOL.KeyVersion.HMAC_SHA1_AES:
        // HMAC-SHA1-128 (WPA2/CCMP)
        break;
    case EAPOL.KeyVersion.AES_128_CMAC:
        // AES-128-CMAC (WPA3, PMF, FT)
        break;
}

API Reference

Frame.from(blob, encoding?)

Parses an EAPOL Key Frame from a buffer or string.

  • blob - Buffer or string containing the EAPOL frame
  • encoding - Optional BufferEncoding (default: 'hex')
  • Returns: Frame
  • Throws: Error if the blob does not contain a valid EAPOL Key Frame

Frame Properties

| Property | Type | Description | |---|---|---| | version | EAPOL.Version | EAPOL protocol version (0x01-0x03) | | type | EAPOL.Type | Packet type (0x03 for EAPOL-Key) | | descriptor | EAPOL.Descriptor | Key descriptor type (RC4, RSN, FT, PMF, FILS, EHT) | | keyVersion | EAPOL.KeyVersion | Crypto algorithm for MIC and key wrapping | | replayCounter | bigint | 8-byte replay counter | | keyLength | number | Pairwise key length in bytes | | keyNonce | Buffer | 32-byte ANonce or SNonce | | keyIv | Buffer | 16-byte initialization vector | | keyRsc | Buffer | 8-byte receive sequence counter | | keyId | Buffer | 8-byte key identifier (reserved) | | mic | Buffer | Message Integrity Code | | zeroedFrame | Buffer | Frame copy with MIC zeroed for verification |

Key Information Flags

| Property | Type | Description | |---|---|---| | keyInfo | EAPOL.KeyInfo | Complete key info structure | | isPairwise | boolean | Pairwise key (PTK) vs group key (GTK) | | hasInstall | boolean | Key should be installed | | hasAck | boolean | From authenticator (AP) | | hasMic | boolean | MIC field is valid | | isSecure | boolean | Secure association established | | hasError | boolean | Error flag | | isRequest | boolean | Supplicant requests new key | | isEncrypted | boolean | Key data is encrypted | | isSmk | boolean | TDLS SMK message |

Handshake Detection

| Property | Type | Description | |---|---|---| | isMessage1 | boolean | Message 1 of 4-way handshake | | isMessage2 | boolean | Message 2 of 4-way handshake | | isMessage3 | boolean | Message 3 of 4-way handshake | | isMessage4 | boolean | Message 4 of 4-way handshake | | messageNumber | 1 \| 2 \| 3 \| 4 \| undefined | Detected message number | | handshakeType | string | 'four-way', 'group-key', or 'unknown' |

Parsed Information Elements

| Property | Type | Description | |---|---|---| | rsn | EAPOL.Rsn \| undefined | RSN IE (WPA2/WPA3) | | wpa | EAPOL.Wpa \| undefined | Legacy WPA IE | | ft | Partial<EAPOL.Ft> \| undefined | Fast Transition IE (802.11r) | | mobilityDomain | EAPOL.MobilityDomain \| undefined | Mobility Domain IE | | ies | EAPOL.Ie[] | All parsed information elements |

Parsed KDEs

| Property | Type | Description | |---|---|---| | gtk | EAPOL.GtkKde \| undefined | Group Temporal Key | | igtk | EAPOL.IgtkKde \| undefined | Integrity Group Temporal Key (PMF) | | pmkid | EAPOL.PmkidKde \| undefined | Pairwise Master Key Identifier | | macAddr | EAPOL.MacAddrKde \| undefined | MAC Address (TDLS) | | smk | EAPOL.SmkKde \| undefined | Station-to-Station Master Key | | nonce | EAPOL.NonceKde \| undefined | Additional nonce | | lifetime | EAPOL.LifetimeKde \| undefined | Key lifetime | | error | EAPOL.ErrorKde \| undefined | Error information | | keyIdKde | EAPOL.KeyIdKde \| undefined | Generic key identifier | | multibandGtk | EAPOL.MultibandGtkKde \| undefined | Multiband GTK | | multibandKeyId | EAPOL.MultibandKeyIdKde \| undefined | Multiband key identifier | | kdes | EAPOL.Kde[] | All parsed KDEs | | encryptedKeyData | Buffer | Raw encrypted key data (if encrypted) |

Frame Methods

validate()

Validates the frame structure and content against IEEE 802.11 requirements.

Returns: { valid: boolean; errors: string[] }

isValidKeyDescriptorVersion()

Checks if the Key Descriptor Version is valid for the Descriptor Type.

Returns: boolean

Non-Goals

This library does not:

  • Capture packets from network interfaces
  • Implement cryptographic operations (PMK/PTK derivation, MIC calculation)
  • Perform active attacks or password cracking
  • Implement EAP authentication protocols
  • Act as a RADIUS server or supplicant

It is purely a parser and validator for already-captured EAPOL frames.

Use Cases

  • Wireless security analysis - Parse captured handshakes
  • DPSK implementations - Validate handshake frames
  • Network monitoring - Extract handshake parameters
  • Research & education - Understand WPA/WPA2/WPA3 protocols
  • Testing & validation - Verify frame structure and compliance
  • Forensics - Analyze captured Wi-Fi traffic

Supported Standards

  • IEEE 802.11i - RSN (WPA2)
  • IEEE 802.11r - Fast Transition (FT)
  • IEEE 802.11w - Protected Management Frames (PMF)
  • IEEE 802.11ai - Fast Initial Link Setup (FILS)
  • IEEE 802.11ac/ax - WPA3, GCMP ciphers
  • Wi-Fi Alliance - WPA, WPA2, WPA3

License

MIT

Contributing

Issues and pull requests welcome at github.com/gibme-npm/eapol

Author

Brandon Lehmann [email protected]