Tor onion services (formerly known as hidden services) provide bidirectional anonymity, end-to-end cryptographic encryption, and NAT traversal without relying on centralized naming authorities or public IPv4/IPv6 routing. Rather than mapping a domain name to an IP address via the public Domain Name System (DNS), an onion service uses an asymmetric public key as its address. This architecture guarantees that network location—both physical and topological—remains hidden from clients, relays, and network adversaries, while simultaneously protecting the user's location from the service operator.
Cryptographic Identity and v3 Address Derivation
Modern hidden services operate almost exclusively on the Version 3 (v3) onion service protocol, introduced to resolve structural weaknesses found in the legacy 80-bit RSA-based v2 system. A v3 address is a base32-encoded representation of the service's master identity key, metadata, and an integrity checksum.
The Anatomy of a 56-Character Address
A v3 onion address consists of 56 characters followed by the .onion pseudo-top-level domain. This string directly encodes three concatenated elements:
- Public Key (32 bytes): A standard Ed25519 public signing key.
- Checksum (2 bytes): A truncated SHA3-256 hash computed over a specific string prefix, the 32-byte public key, and the version byte.
- Version Byte (1 byte): The constant integer
0x03, denoting the v3 protocol.
When concatenated, these 35 bytes are encoded using RFC 4648 base32 alphabet, producing exactly 56 ASCII characters:
checksum = SHA3-256(".onion checksum" || public_key || version)[:2]
onion_address = base32(public_key || checksum || version) || ".onion"
Because the address is self-authenticating, Man-in-the-Middle (MitM) attacks are mathematically impossible without compromising the underlying Ed25519 private key. A client connecting to an onion address verifies that the server possesses the corresponding private key during the protocol handshake, eliminating reliance on third-party Certificate Authorities (CAs).
Decentralized Discovery: Key Blinding and the HSDir DHT
In classical client-server models, a client issues a DNS query to find an IP address. In Tor, an onion service registers its availability using a distributed hash table (DHT) composed of relays holding the HSDir (Hidden Service Directory) flag.
Key Blinding for Query Privacy
To prevent HSDir nodes from cataloging all registered services or harvesting .onion addresses, the protocol employs key blinding. The service does not publish its real Ed25519 identity key. Instead, both the service and the client derive a temporary blinded public key using the service’s master key and a shared time period parameter derived from UTC time:
blinded_key = master_pubkey + H(master_pubkey || time_period) * G
The service descriptor is then signed using the matching blinded private key. Because of the discrete logarithm hardness over Curve25519, an HSDir relay storing the descriptor cannot reverse the blinded key to discover the actual .onion address. Only a client that already knows the original .onion address can compute the blinded key, locate the correct HSDir nodes in the DHT ring, and fetch the descriptor.
The Service Descriptor
The descriptor contains the operational parameters required to reach the service, including:
- The blinded public key.
- A list of chosen Introduction Points.
- Authentication keys and encryption keys for each introduction point.
- An optional client authorization layer (using X25519 keys) to encrypt the descriptor payload.
Step-by-Step Circuit Assembly: Connecting Client to Service
Establishing communication between a client and an onion service requires six separate Tor relays and the construction of two distinct circuits that meet at an intermediate node called the Rendezvous Point.
Step 1: Introduction Point Selection
When an onion service launches, it randomly selects three to ten Tor relays to act as its Introduction Points (IPs). The service builds a standard three-hop Tor circuit to each selected relay and transmits an ESTABLISH_INTRO cell. This message instructs the relay to listen for incoming introduction requests tied to a unique authentication key. These circuits remain open indefinitely as long-lived control channels.
Step 2: Publishing the Descriptor
The service packages its list of Introduction Points, encrypts the payload, signs it using its blinded key, and distributes this descriptor to the appropriate HSDir relays in the consensus DHT. The descriptor is republished periodically as the time period advances or Introduction Points rotate.
Step 3: Client Fetch and Rendezvous Preparation
When a user requests access to an onion address:
- The client derives the current blinded key from the address and requests the descriptor from the corresponding HSDir relays over an anonymized three-hop circuit.
- The client validates the cryptographic signature and decrypts the descriptor payload.
- The client chooses a random relay in the Tor network to act as the Rendezvous Point (RP).
- The client builds a three-hop circuit to the chosen RP and sends an
ESTABLISH_RENDEZVOUScell containing a secret 20-byte random value known as the Rendezvous Cookie.
Step 4: The Introduction Request
The client builds a separate three-hop circuit to one of the service’s Introduction Points listed in the descriptor. It delivers an INTRODUCE1 cell containing:
- The identity of the selected Rendezvous Point.
- The 20-byte Rendezvous Cookie.
- The first half of an ephemeral Diffie-Hellman handshake (using Curve25519 via the ntor key exchange).
This payload is end-to-end encrypted using the onion service’s public encryption key found in the descriptor. The Introduction Point cannot read this payload; it merely unpacks the outer layer and forwards an INTRODUCE2 cell containing the encrypted data down its pre-established circuit to the onion service.
Step 5: The Rendezvous Connection and Circuit Splicing
Upon receiving and decrypting the INTRODUCE2 cell, the service learns the RP address, the Rendezvous Cookie, and the client's ephemeral public key. The service then:
- Completes the ntor handshake, deriving shared symmetric keys (
k_clientandk_service) via HKDF-SHA256. - Builds its own three-hop circuit to the client’s designated Rendezvous Point.
- Sends a
RENDEZVOUS1cell to the RP containing the 20-byte Rendezvous Cookie and its own ephemeral Diffie-Hellman public key.
The Rendezvous Point checks the received cookie against its active rendezvous list. Matching the client's established session with the incoming service connection, the RP forwards the service’s handshake response to the client in a RENDEZVOUS2 cell. Finally, the RP splices the two three-hop circuits together.
Client <---> Guard <---> Middle <---> RP <---> Middle <---> Guard <---> Service
|___________________________________| |__________________________________|
Client's 3-hop Circuit Service's 3-hop Circuit
The resulting path is a six-hop channel. The Rendezvous Point acts as an oblivious bridge: it sees traffic passing between two Tor circuits, but it does not know the identity or IP address of the client, the identity or IP address of the service, or the plaintext data flowing between them.
Traffic Isolation and Defensive Hardening
While the onion service protocol provides mathematical confidentiality and anonymity at the network routing layer, real-world deployment requires defensive engineering to prevent traffic analysis and host-level de-anonymization.
Guard Discovery Mitigations: Vanguards
Adversaries operating malicious relays can attempt guard discovery attacks by repeatedly building rendezvous circuits or manipulating traffic to force the service to choose new middle relays, eventually mapping the service's permanent Entry Guard. To mitigate this threat, operators deploy the Vanguards addon (integrated into standard Tor via Vanguard-lite for onion services). This mechanism pins middle hops to a small, slowly rotating pool of relays, preventing attackers from forcing rapid path churn to uncover entry points.
Application Layer Leakage
A misconfigured web server can bypass onion routing entirely by leaking its real IPv4 or IPv6 address. Defensive mitigations include:
- Binding the application daemon strictly to
localhost(127.0.0.1 or unix sockets) to prevent external interface enumeration. - Disabling outbound network connections at the OS kernel level (e.g., via
iptablesornftables), ensuring that the web application cannot initiate external TCP requests to fetch remote resources, fonts, or tracking scripts. - Stripping HTTP metadata, server signature banners, and unique error stack traces that could be fingerprinted via tools like Shodan to find matching public-facing hosts.
Proof-of-Work (PoW) DoS Defense
Because processing an INTRODUCE2 cell requires asymmetric cryptographic computation (X25519 and Ed25519 operations), malicious actors can launch Denial of Service (DoS) attacks by flooding introduction points with bogus requests. Modern Tor versions (0.4.8.x and later) introduce dynamic client-side Proof-of-Work mechanisms using the Equi-X algorithm. Under heavy load, the service instructs clients via the descriptor to solve a computational puzzle before forwarding an introduction request, prioritizing legitimate users while making distributed floods computationally expensive for attackers.
Conclusion
The .onion protocol achieves mutual anonymity and integrity by combining asymmetric key-pair addressing, dynamic distributed lookup, ephemeral Diffie-Hellman key exchanges, and multi-hop circuit splicing. By decoupling network identity from physical topology and standard IP infrastructure, onion services provide a resilient, self-authenticating, and surveillance-resistant communications layer suitable for sensitive journalism, secure software distribution, and adversarial defensive computing.