What Encryption Algorithm Does OpenFlux Use? AES-256-GCM Deep Dive
OpenFlux uses AES-256-GCM authenticated encryption to secure all traffic between clients and exit nodes, deriving keys via scrypt and HMAC-SHA-256 to ensure confidentiality and integrity.
OpenFlux is an open-source networking tool designed to tunnel traffic between peers while hiding payloads from underlying transport providers. Understanding what encryption algorithm OpenFlux uses is critical for security audits and deployment decisions. According to the p1neappleXpress/OpenFlux source code, the project implements a robust cryptographic layer centered on AES-256-GCM, with additional protections against replay attacks and key compromise.
How OpenFlux Implements AES-256-GCM Encryption
The encryption system in OpenFlux follows a strict hierarchy: key derivation produces a master secret, directional keys isolate traffic flows, and the AES-256-GCM AEAD construction provides authenticated encryption. This architecture is implemented primarily in transport/encrypted.go.
Key Derivation with Scrypt
OpenFlux begins by combining a shared secret (minimum 16 bytes) with a public context string to establish entropy. The derivation process uses scrypt with specific parameters to resist brute-force attacks.
In transport/encrypted.go lines 58-62, the implementation constructs a SHA-256-based salt using the format "OpenFlux encrypted transport v1\x00"+context. The shared secret is then processed through scrypt with N=32768, r=8, p=1, producing a 32-byte master key. These parameters balance memory hardness with performance, making dictionary attacks computationally expensive while maintaining reasonable connection speeds.
Directional Key Separation via HMAC-SHA-256
To prevent a compromise of one communication direction from exposing the other, OpenFlux generates two distinct keys using HMAC-SHA-256. As shown in lines 90-94 of transport/encrypted.go, the master key is fed into HMAC-SHA-256 with directional labels:
"client-to-exit"for upstream traffic"exit-to-client"for downstream traffic
This isolation ensures that even if an attacker extracts the client-to-exit key, they cannot decrypt exit-to-client responses without breaking the HMAC construction.
AEAD Construction and Packet Encryption
Each directional key initializes a separate AES-256-GCM cipher. Lines 96-105 in transport/encrypted.go demonstrate the construction: aes.NewCipher creates the block cipher, and cipher.NewGCM wraps it as an AEAD interface.
Every packet follows a strict binary format defined in lines 8-19:
- A 3-byte magic header (
"OFX") - One version byte
- One direction byte
- A random nonce sized for GCM requirements
- The encrypted payload via
AEAD.Seal
This structure ensures that receivers can verify packet authenticity and integrity before decryption, preventing tampering and truncation attacks.
Replay Protection Mechanism
OpenFlux includes built-in replay protection to prevent attackers from retransmitting captured packets. The implementation maintains a bounded cache of seen nonces with maxSeenNonces = 4096 entries (lines 42-56 in transport/encrypted.go).
Before processing any received packet, the transport checks if the nonce exists in the cache. Duplicate nonces trigger an immediate rejection, ensuring that each encrypted payload is processed exactly once. This protection complements the AES-256-GCM authentication tag, providing defense-in-depth against replay-based traffic analysis.
Code Implementation Details
The encryption layer is exposed through the EncryptedTransport type in transport/encrypted.go, which wraps any implementation of the Transport interface defined in transport/transport.go.
Initializing the Encrypted Transport
To create an encrypted tunnel, applications instantiate the transport with a shared secret and context identifier:
import "github.com/p1neappleXpress/OpenFlux/main/transport"
// inner is any Transport implementation (e.g., from tunnel/packettunnel.go)
secret := "my-super-secret-shared-key"
context := "session-1234"
exitNode := false // set true on the exit side
enc, err := transport.NewEncryptedTransport(inner, secret, context, exitNode)
if err != nil {
// handle error
}
The NewEncryptedTransport function handles all key derivation internally, applying scrypt and HMAC-SHA-256 to prepare the AES-256-GCM instances for both directions.
Sending and Receiving Data
Once established, the transport provides symmetric encryption transparently:
// Sending encrypted data
payload := []byte("Hello, OpenFlux!")
if err := enc.Send(payload); err != nil {
// handle error
}
// Receiving and decrypting data
enc.Receive(func(plain []byte) {
fmt.Printf("Decrypted: %s\n", plain)
})
The Send method automatically applies the correct directional key, generates a fresh random nonce, and invokes AEAD.Seal before transmitting over the underlying transport. Similarly, Receive validates nonces against the replay cache, verifies the authentication tag, and returns plaintext via the callback.
Security Architecture Overview
The cryptographic design spans multiple files in the repository:
transport/encrypted.go: Implements AES-256-GCM encryption, scrypt key derivation, HMAC-SHA-256 directional keys, and nonce-based replay protectiontransport/transport.go: Defines the abstractTransportinterface thatEncryptedTransportwrapstunnel/packettunnel.go: Provides concrete packet-level transport implementations that can be secured by the encryption layerutils/logging.go: Supplies centralized debugging output for the encrypted transport operations
Together, these components create end-to-end encrypted tunnels where tunnel/packettunnel.go handles raw packet forwarding while transport/encrypted.go ensures all payloads remain confidential and tamper-proof through AES-256-GCM.
Summary
- OpenFlux uses AES-256-GCM for authenticated encryption of all peer-to-peer traffic
- Keys are derived via scrypt (N=32768, r=8, p=1) with SHA-256 salts to resist brute-force attacks
- HMAC-SHA-256 creates directional keys ("client-to-exit" and "exit-to-client") to isolate traffic streams
- Replay protection uses a 4096-entry nonce cache to reject duplicate packets
- The implementation resides primarily in
transport/encrypted.go, wrapping generic transports defined intransport/transport.go
Frequently Asked Questions
Does OpenFlux use end-to-end encryption?
Yes. OpenFlux implements end-to-end encryption between the client and exit node using AES-256-GCM. The encryption keys are derived from a pre-shared secret using scrypt, ensuring that only peers possessing the correct secret can decrypt traffic, while the underlying transport provider sees only encrypted payloads.
What are the scrypt parameters used by OpenFlux?
OpenFlux uses scrypt with N=32768, r=8, and p=1 to derive the master key from the shared secret. These settings provide memory-hard key derivation that slows brute-force attempts while maintaining acceptable performance for tunnel establishment. The output is a 32-byte key suitable for AES-256.
How does OpenFlux prevent replay attacks?
OpenFlux prevents replay attacks by maintaining a bounded cache of the last 4096 nonces (maxSeenNonces = 4096) as implemented in transport/encrypted.go. Each packet must contain a unique nonce; if the transport encounters a nonce it has already processed, it rejects the packet immediately before attempting decryption.
Can I use OpenFlux encryption with custom transports?
Yes. The EncryptedTransport type implements the generic Transport interface defined in transport/transport.go, allowing it to wrap any compatible transport implementation. You can pass custom transports to NewEncryptedTransport, and the layer will automatically encrypt all data using AES-256-GCM before handing it to the underlying implementation.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →