Noise Protocol Framework
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
The Noise Protocol Framework in this project serves as the core cryptographic communication layer between the client and the WhatsApp servers. It provides end-to-end encrypted framing, handshake processing, and secure key derivation to ensure data integrity and confidentiality. The implementation utilizes the Noise Protocol patterns to establish a secure session before any binary protocol data is exchanged.
The framework is encapsulated primarily within the makeNoiseHandler utility, which manages stateful encryption/decryption counters, handshake certificates, and the accumulation of incoming bytes into structured frames. By integrating with the project's binary node system, it allows for seamless processing of high-level commands over an encrypted transport.
Sources: lib/Utils/noise-handler.js:13-25, lib/Utils/noise-handler.d.ts
Core Architecture and Handshake
The Noise Handler is initialized with a local key pair, a noise header, and optional routing information. During the initialization phase, it sets up initial hash and salt values derived from the NOISE_MODE. The handshake process involves exchanging ephemeral keys and verifying the server's certificate chain to establish a shared secret.
Handshake Flow
The following diagram illustrates the transition from initial connection to a finished handshake state:
The handshake ensures that the server is legitimate by checking the issuerSerial against the expected WA_CERT_DETAILS.SERIAL.
Sources: lib/Utils/noise-handler.js:68-87, WAProto/Cert/Cert.js:847-860
Cryptographic Operations
The framework uses AES-GCM for encryption and decryption, with HMAC-based Key Derivation Function (HKDF) for key rotations. A unique initialization vector (IV) is generated for each operation using a 32-bit counter.
Key Features
| Feature | Implementation Detail |
|---|---|
| Encryption | AES-GCM using encKey, current writeCounter, and hash as authenticated data. |
| Decryption | AES-GCM using decKey and readCounter. Handshake uses writeCounter for read until finished. |
| Key Derivation | HKDF with a 64-byte output, split into write and read keys. |
| Authentication | Continuous hashing of sent/received data to maintain protocol state integrity. |
Sources: lib/Utils/noise-handler.js:20-55
IV Generation Logic
const generateIV = (counter) => {
const iv = new ArrayBuffer(12)
new DataView(iv).setUint32(8, counter)
return new Uint8Array(iv)
}
Sources: lib/Utils/noise-handler.js:13-17
Framing and Buffering
Data is transmitted in frames prefixed by a 3-byte size header. The Noise Handler accumulates incoming bytes until a complete frame is available for decryption and decoding.
Data Flow for Incoming Frames
A safety mechanism MAX_BUFFER_SIZE (10MB) is implemented to prevent memory exhaustion if the accumulation buffer grows uncontrollably due to malformed packets or slow processing.
Sources: lib/Utils/noise-handler.js:90-149, lib/WABinary/generic-utils.js:115-131
Certificate Handling
The Noise Protocol utilizes a specialized certificate structure defined in the Cert namespace. This includes a CertChain consisting of leaf and intermediate Noise Certificates. Each certificate contains binary details and a signature.
Certificate Structure Details
| Field | Type | Description |
|---|---|---|
| serial | uint32 | Unique serial number of the certificate. |
| issuerSerial | uint32 | Serial number of the issuing authority. |
| key | bytes | The public key associated with the certificate. |
| notBefore | uint64 | Timestamp for certificate validity start. |
| notAfter | uint64 | Timestamp for certificate expiration. |
Sources: WAProto/Cert/Cert.d.ts:252-273, WAProto/Cert/Cert.js:464-478
Protocol Stability and Maintenance
The noise-handler includes lifecycle management to ensure clean resource handling:
- destroy(): Sets an
isDestroyedflag and clears the internalinBytesbuffer to release memory and stop processing. - Routing Info: Supports optional
routingInfoduring frame encoding, which adds a specific header (identifying as "ED") before the standard Noise header.
Sources: lib/Utils/noise-handler.js:93-109, lib/Utils/noise-handler.js:154-158
Conclusion
The Noise Protocol Framework provides the fundamental security layer for the project, managing the transition from raw TCP/WebSocket streams to a secure, authenticated binary protocol. Through strict handshake verification, stateful encryption counters, and robust framing, it ensures that all client-server interactions remain protected against unauthorized interception or modification.