Trojan is a proxy protocol that hides inside TLS, the same encryption that protects HTTPS websites. Your device opens a normal TLS connection to the server, usually on port 443, and sends a password and the address you want to reach inside it. If the password is wrong, the server behaves like an ordinary website, so to an observer the Trojan proxy protocol looks like everyday HTTPS browsing.
This explainer covers what Trojan is, how it works, its transports and REALITY, its strengths and weaknesses, and how to read a trojan:// link. Ready to set one up? See how to use Trojan on iPhone.
What is the Trojan proxy protocol?
Despite the name, Trojan has nothing to do with malware. The name comes from the Trojan horse: proxy traffic travels inside something that looks harmless and familiar.
Trojan doesn’t invent its own encryption. It relies on TLS for that, and adds a very small header on top: a hash of your password, a command, and the destination address. That makes the protocol simple, and it means the encryption is the same well-studied TLS used by banks and browsers.
The design goal is to blend in. Most traffic on the internet today is HTTPS on port 443. A Trojan server sits on that port with a real domain name and certificate, and anything that isn’t a valid Trojan client gets a real web page back.
A brief history
The original implementation, trojan-gfw, was written in C++ and appeared around 2019. Its specification is published on the project’s protocol page. A Go rewrite, trojan-go, followed and added WebSocket transport and multiplexing. Today Trojan is built into most multi-protocol servers and clients, including Xray, sing-box and Mihomo, and those projects added more transports and REALITY support.
How Trojan works
- TLS handshake. Your client connects to the server, usually on port 443, and starts TLS with a server name (SNI) such as
trojan.example.com. The server presents a valid certificate for that name. - Trojan request. Inside the encrypted connection, the client sends the SHA-224 hash of the password, a command (connect, or UDP associate), and the destination, such as
example.org:443. - Check. The server compares the hash with its users’ passwords.
- Relay or fallback. If the hash matches, the server connects to the destination and relays data both ways. If it doesn’t, the server hands the whole connection to a fallback web server, so the visitor sees an ordinary website.
- UDP. UDP packets travel framed inside the same TLS connection.
iPhone ──TLS (SNI trojan.example.com)──▶ Trojan server ──▶ example.org
│
wrong password ──────┴──▶ ordinary website (fallback)
The fallback is what makes Trojan different from Shadowsocks. A probe that connects to the server gets a normal web page, not a dropped connection.
Transports: TLS only, WebSocket and gRPC
Plain Trojan runs directly over TLS. Most servers also offer a transport that carries the Trojan stream inside another protocol:
- WebSocket runs inside a regular HTTPS request. Because CDNs and reverse proxies understand WebSocket, the server can sit behind a CDN and keep its real IP address private.
- gRPC runs over HTTP/2 and also passes through many CDNs and reverse proxies.
- HTTP/2 and HTTP Upgrade are similar options some servers use.
Transports add some overhead and more settings to get right, such as a path or a service name. Use one only if your server is set up for it.
Trojan with REALITY
A classic Trojan server needs its own domain and certificate. REALITY, created in the Xray project, removes that need. The server borrows the TLS handshake of a real, unrelated website. Clients that know the server’s public key and short ID get the proxy. Everyone else is passed through to the real website.
REALITY usually goes with VLESS, but Trojan servers can use it too. Learn more in What is VLESS + REALITY?
Strengths and weaknesses
Strengths
- Looks like normal HTTPS on port 443.
- Answers probes with a real website instead of silence.
- Uses standard TLS rather than custom cryptography.
- Simple to implement, so it’s widely supported.
- Carries UDP as well as TCP.
Weaknesses
- Needs a domain and a valid certificate, unless you use REALITY.
- A client’s TLS handshake can differ from a browser’s. Clients offer a browser fingerprint option to match one, but it’s an imitation.
- Researchers have shown that TLS running inside TLS, as when you browse HTTPS sites through Trojan, can leave patterns in packet sizes and timing.
- A wrong password produces no error, only the fallback website, which makes mistakes harder to spot.
- UDP inside a TCP connection can suffer when packets are lost, which games and calls notice.
Trojan vs Shadowsocks vs VLESS vs VMess
| Trojan | Shadowsocks | VLESS | VMess | |
|---|---|---|---|---|
| Encryption | TLS | Its own ciphers | TLS or REALITY | Its own, optional TLS |
| Looks like | HTTPS | Random bytes | HTTPS | Random bytes, or HTTPS with TLS |
| Needs a certificate | Yes, or REALITY | No | Yes, or REALITY | Only with TLS |
| UDP | Yes | Yes | Yes | Yes |
| Credential | Password | Password or key | UUID | UUID |
For a deeper comparison, read What is Shadowsocks?, VMess vs VLESS and Proxy protocols compared.
What a trojan:// link looks like
Providers share Trojan servers as trojan:// links, often as QR codes:
trojan://password@host:port?parameters#name
passwordis the server password, percent-encoded.hostandportare the server address and port (443 if left out).parametersset TLS and the transport:snifor the server name,typefor the transport (tcp,ws,grpc),hostandpathfor WebSocket,serviceNamefor gRPC, andsecurity=realitywithpbkandsidfor REALITY.nameis what the app shows.
Some examples, with the password secret:
trojan://secret@trojan.example.com:443?sni=trojan.example.com#Basic
trojan://secret@trojan.example.com:443?security=tls&type=ws&host=cdn.example.com&path=%2Fws#WebSocket
trojan://secret@trojan.example.com:443?security=tls&type=grpc&serviceName=TrojanGun#gRPC
trojan://secret@trojan.example.com:443?security=reality&sni=www.example.com&pbk=Z84J2IelR9ch3k8VtlVhhs5ycBUlXA7wHBWcBrjqnAw&sid=0123abcd&fp=chrome#REALITY
Every parameter Potatso reads is listed in the Trojan reference.
Use Trojan on iPhone
iOS has no built-in Trojan support, so you need a client app. Potatso is a free proxy client for iPhone and iPad that imports trojan:// and trojan-go:// links, QR codes and Clash subscriptions, and supports WebSocket, gRPC, HTTP/2, HTTP Upgrade and REALITY. Follow the step-by-step guide: How to use Trojan on iPhone.
Frequently asked questions
- Is the Trojan proxy protocol a virus?
- No. Trojan is a proxy protocol, not malware. It's named after the Trojan horse because it hides proxy traffic inside an ordinary-looking HTTPS connection, not because it harms your device.
- Does Trojan need a domain name and certificate?
- A classic Trojan server needs a domain name and a valid TLS certificate, because the connection is real TLS. A Trojan server with REALITY borrows another website's TLS handshake instead, so it doesn't need a certificate of its own.
- What port does Trojan use?
- Usually 443, the standard HTTPS port, so the connection looks like normal web traffic. Any port works if the server is set up for it, and trojan:// links that leave the port out use 443.
- Does Trojan support UDP?
- Yes. Trojan carries UDP inside the same TLS connection as TCP. In Clash-compatible clients, including Potatso, UDP is off by default for Trojan servers, so turn it on if your server relays UDP.
- Is Trojan better than Shadowsocks?
- It depends on the network. Trojan looks like HTTPS and answers probes like a real website, while Shadowsocks is simpler, needs no certificate and has less overhead. Many providers offer both, so you can try each.