@gibme/eapol
v20.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
174
Maintainers
Readme
@gibme/eapol is a comprehensive, low-level EAPOL (Extensible Authentication Protocol over LAN) Key Frame parser for Wi-Fi security protocols.
It parses and validates EAPOL-Key frames used in WPA/WPA2/WPA3 4-way handshakes, group key handshakes, and Fast Transition (802.11r) operations.
Features
Frame Parsing
- Parse complete EAPOL-Key frames from buffers or hex strings
- Automatic frame detection (scans up to 512 bytes for EAPOL header)
- Supports EAPOL versions 1, 2, and 3 (802.1X-2001/2004/2010)
- Extracts all key descriptor fields (nonces, MIC, replay counter, etc.)
- Parses Key Information flags with full bit-field decoding
Security Protocol Support
- WPA/TKIP: Legacy WPA with Microsoft OUI (00:50:F2:01)
- WPA2/WPA3: RSN Information Element (IE 0x30) parsing
- 802.11r (Fast Transition): Full FT-IE and Mobility Domain parsing
- 802.11w (PMF): Management Frame Protection with IGTK support
- 802.11ai (FILS): Fast Initial Link Setup support
Key Data Encapsulation (KDE) Parsing
- GTK: Group Temporal Key for multicast/broadcast traffic
- IGTK: Integrity Group Temporal Key for management frame protection
- PMKID: Pairwise Master Key Identifier for fast roaming
- MAC Address: TDLS peer identification
- SMK: Station-to-Station Master Key (TDLS)
- Nonce, Lifetime, Error: Additional key metadata
- Multiband: Multi-band operation support
Cipher Suite & AKM Support
Complete constants for all standard cipher suites and AKM (Authentication and Key Management) methods:
Cipher Suites:
- WEP-40/104 (legacy)
- TKIP (WPA)
- CCMP-128/256 (WPA2/WPA3)
- GCMP-128/256 (WPA3, 802.11ac/ax)
- BIP-CMAC/GMAC-128/256 (PMF)
AKM Suites:
- PSK, EAP (WPA2-Personal/Enterprise)
- SAE (WPA3-Personal)
- FT (802.11r Fast Transition variants)
- FILS (802.11ai Fast Initial Link Setup)
- OWE (Opportunistic Wireless Encryption)
- Suite-B-192 (WPA3-Enterprise 192-bit)
Frame Validation
Comprehensive validation including:
- EAPOL version and descriptor compatibility
- Key Information flag consistency (per 802.11 spec)
- Message-specific requirements (Messages 1-4 of 4-way handshake)
- Replay counter validation
- IE/KDE structure validation
- Nonce and MIC presence requirements
Frame Type Detection
- Automatic 4-way handshake message detection (Messages 1-4)
- Group key handshake identification
- Handshake type classification (four-way, group-key, unknown)
Installation
npm install @gibme/eapolUsage
Parse an EAPOL Frame
import { Frame } from '@gibme/eapol';
// From hex string
const frame = Frame.from('0203005f02...', 'hex');
// From buffer
const frame = Frame.from(buffer);
// Access parsed data
console.log(`Message ${frame.messageNumber} of 4-way handshake`);
console.log(`Replay Counter: ${frame.replayCounter}`);
console.log(`ANonce: ${frame.keyNonce.toString('hex')}`);
console.log(`Has MIC: ${frame.hasMic}`);
console.log(`MIC: ${frame.mic.toString('hex')}`);Identify Handshake Messages
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('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);
}
// 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'));
}Validate 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!');
}Compare Cipher Suites
import { EAPOL } from '@gibme/eapol';
const frame = Frame.from(buffer);
if (frame.rsn) {
// Check if CCMP-128 is supported
const supportsCCMP = frame.rsn.pairwiseCipherSuites.some(
suite => suite.equals(EAPOL.PairwiseCipherSuite.CCMP_128)
);
// Check if SAE (WPA3) is supported
const supportsSAE = frame.rsn.akmSuites.some(
suite => suite.equals(EAPOL.AkmSuite.SAE)
);
console.log('Supports CCMP-128:', supportsCCMP);
console.log('Supports WPA3-SAE:', supportsSAE);
}API Reference
Frame.from(blob, encoding?)
Parses an EAPOL Key Frame from a buffer or string.
Parameters:
blob- Buffer or hex string containing the EAPOL frameencoding- Optional encoding (default: 'hex')
Returns: Frame object
Throws: Error if blob does not contain a valid EAPOL Key Frame
Frame Properties
Header Fields
version- EAPOL protocol version (0x01, 0x02, 0x03)type- EAPOL packet type (typically 0x03 for EAPOL-Key)descriptor- Key Descriptor Type (RC4, RSN, FT, PMF, FILS, EHT)keyVersion- Key Descriptor Version (indicates MIC/encryption algorithm)replayCounter- 8-byte replay counter (bigint)
Key Fields
keyLength- Key length in byteskeyNonce- 32-byte nonce (ANonce or SNonce)keyRsc- 8-byte Receive Sequence CounterkeyIv- 16-byte Initialization VectorkeyId- 8-byte key identifier (reserved)mic- 16-byte Message Integrity CodezeroedFrame- Frame copy with MIC zeroed (for verification)
Key Information Flags
keyInfo- Complete KeyInfo objectisPairwise- Pairwise key (PTK) vs group key (GTK)hasInstall- Install flag sethasAck- ACK flag set (from authenticator)hasMic- MIC flag setisSecure- Secure flag sethasError- Error flag setisRequest- Request flag setisEncrypted- Key Data encryptedisSmk- TDLS SMK message
Handshake Detection
isMessage1- Message 1 of 4-way handshakeisMessage2- Message 2 of 4-way handshakeisMessage3- Message 3 of 4-way handshakeisMessage4- Message 4 of 4-way handshakemessageNumber- Returns 1, 2, 3, 4, or undefinedhandshakeType- 'four-way', 'group-key', or 'unknown'
Parsed Information Elements
rsn- RSN Information Element (WPA2/WPA3)wpa- WPA Information Element (legacy)ft- Fast Transition Information ElementmobilityDomain- Mobility Domain IEies- Array of all Information Elements
Parsed KDEs
gtk- Group Temporal Keyigtk- Integrity Group Temporal Key (PMF)pmkid- Pairwise Master Key IdentifiermacAddr- MAC Address (TDLS)smk- Station-to-Station Master Keynonce- Additional noncelifetime- Key lifetimeerror- Error informationkeyIdKde- Generic key identifiermultibandGtk- Multiband GTKmultibandKeyId- Multiband key identifierkdes- Array of all KDEs
Other
encryptedKeyData- Encrypted key data (if encrypted)
Frame Methods
validate()
Validates the frame structure and content.
Returns: { valid: boolean, errors: string[] }
isValidKeyDescriptorVersion()
Checks if the Key Descriptor Version is valid for the Descriptor Type.
Returns: boolean
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
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
TypeScript Support
Full TypeScript definitions included. All types, enums, and constants are exported.
import { Frame, EAPOL } from '@gibme/eapol';
// Full type safety
const frame: Frame = Frame.from(buffer);
const version: EAPOL.Version = frame.version;
const rsn: EAPOL.Rsn | undefined = frame.rsn;Performance
- Optimized for correctness and clarity
- Pure TypeScript with minimal dependencies
- Suitable for real-time packet analysis
- Can parse thousands of frames per second on modern hardware
Security Considerations
- Input data is parsed defensively with bounds checking
- Validates frame structure before parsing
- Detects truncated or malformed frames
- Does not execute any cryptographic operations
- Designed for analysis of captured traffic, not active network operations
License
MIT
Contributing
Issues and pull requests welcome at github.com/gibme-npm/eapol
Author
Brandon Lehmann [email protected]
