Skip to content

Security & privacy

What protects a Tether session.

Windows + Android Last reviewed 14 August 2026

Tether puts your PC's screen on your phone. That is an enormous amount of trust to ask for, so this page is written to be checked rather than believed: what the encryption actually is, what our servers genuinely can see, and a full section on what none of it protects you from.

1. The short answer

Your screen, the PC's sound, your taps and keystrokes and any file you move all go straight from one device to the other, encrypted at one end and decrypted at the other. Our server introduces the two devices and then steps out. It holds no key that would let it read anything that passes.

Your PC shows an eight-character code and you type it into your phone. That code is never transmitted, not to us and not even to your phone. Both devices use it as a secret ingredient in a standard handshake, and only the result of that maths crosses the network. Someone recording the whole exchange learns nothing about the code.

What we can see is the fact of the connection: that a device at one address met a device at another address, in a particular room, at a particular time. Section 4 says so plainly rather than rounding it down to "we see nothing".

If you read one section, read section 6. A security page that lists its strengths and not its gaps is an advertisement.

2. How a pairing works

The code is cut in two

Eight characters, from an alphabet of 32: the digits 2 to 9 and the letters A to Z, with 0, O, 1 and I left out so nothing is ambiguous when you copy it off a screen.

The first three characters are public. They name a meeting room on our server, which is how your devices find each other. The last five are the password, and they never reach our server in any form, so the relay cannot learn them even in principle. The room name is not made from the password, so nobody who learns it can take it away and grind through guesses offline.

Five characters from 32 symbols is 33,554,432 combinations.

The handshake

Pairing uses SPAKE2, a published standard (RFC 9382), not a scheme we invented. Neither app hand-rolls the maths: each takes it from an established library pinned to an exact version, and section 7 names them, including the one place the phone's library falls short of the standard.

Both devices end up with the same key only if both knew the code. There is no partial credit and no "warmer" signal to narrow a search with. A guess either completes or it does not.

Guessing is throttled, twice

  • Five wrong tries from one address freeze that address for 30 seconds.
  • Ten wrong tries from anywhere at all freeze everybody for 45 seconds.

The second limit exists because a single home internet subscriber is routinely handed billions of addresses, so a per-address limit alone is a speed bump. At the fastest rate those limits allow, working through half of the 33.5 million possibilities takes about two and a half years. That is arithmetic from the two numbers above, not an attack anyone has run.

A wrong guess does not burn the code

Typing it wrong does not force a new one, so a stranger making one bad guess cannot strand you halfway through your own pairing. The code expires on its own after ten minutes with no pairing activity, and it is replaced after a successful pairing and when the app restarts. It will never rotate while you are mid-way through typing it.

Nothing leaves the PC before the phone has proved itself

An unverified phone is negotiated with on a separate connection built with no screen attached to it at all. The real screen is plugged in only once the PC has verified the phone's proof, so there is no window in which a frame could escape to someone who guessed wrong.

The PC's own Tether window is hidden from screen recording and screenshots by the operating system, always, with no setting to get wrong.

The phone is deliberately not the same. Android can blank the app the same way and Tether offers it as a switch, "Block screenshots & recording", but it ships off because many people reasonably want to record or cast their own session. With it off, anything recording your phone's screen can see the code while you type it. The switch is in Settings and covers the whole app.

What the phone keeps afterwards

A key that was never transmitted: both devices worked it out independently from the handshake. It moves forward on every reconnection, so a stolen copy goes stale on its own.

Stale is not instantly dead. The PC keeps the current key and the one before it, so a stolen copy works for one more reconnection and dies on the second. That grace exists because without it, one lost confirmation message would lock you out of your own PC. The first time a key is used out of step, the PC records it as a possible copy.

The phone also pins the PC's certificate. If it ever sees a different one it stops and says "This PC doesn't look like the one you paired with…" rather than connecting anyway. The only ways back are deliberate: scan the PC's QR code again, or forget the PC and start over.

That pin is only accepted from a route that is already trustworthy: through the QR code, which travels from the PC's screen to the phone's camera and never touches the network, or inside the handshake under a tag only a device holding the handshake secret could produce. A tampered tag aborts the pairing, and a pin learned from the QR code is never overwritten.

3. What protects a live session

Everything rides on one standard WebRTC connection encrypted with DTLS-SRTP, the same mechanism that protects browser video calls. It carries the screen, the PC's sound, and three data channels: control and file transfer, both of which never drop anything, and cursor movement, which is allowed to drop packets because a mouse position that arrives late is worse than one that never arrives.

Tether does not choose the encryption algorithm. The two WebRTC implementations negotiate it at runtime and nothing in our code pins one, so we name the mechanism, which you can check in our source, and not an algorithm we cannot guarantee.

Why the relay cannot quietly sit in the middle

"The server just passes messages along" is not a guarantee by itself: a server that passes messages along could substitute its own instead.

So both devices fold the connection's cryptographic fingerprints into the proof they exchange while pairing. Anything that re-terminated the connection in the middle would change a fingerprint, the two sides would compute different keys, the proofs would not match, and pairing aborts. That is a property of the maths, not a promise about our conduct. The same binding protects every later reconnection, each with fresh random values from both sides so a recorded proof cannot be replayed.

One detail, because this is the sort of thing that fails quietly: if a setup message carries more than one fingerprint and they disagree, pairing aborts rather than picking one. Without that check a relay could send a decoy alongside a rewritten real one, every proof would still verify, and it would be holding both halves of the call.

The PC does not listen to the whole network

The PC's listener always covers the machine itself, and reaches your home network only when home-network access is switched on, when a phone is already paired, and while the pairing card is open on screen. It never listens on everything. Any connection arriving with a web-page origin attached is refused outright, which closes the trick where a malicious website talks to software on your own machine.

4. What our servers can and cannot see

One server of ours, the switchboard. Its only job is to let your two devices find each other and swap the messages that start a direct connection.

What it cannot see

  • Your screen, the PC's sound, your keystrokes, your clicks, your files. None of it passes through the switchboard, and it holds no key that could decrypt it.
  • The secret half of your pairing code. Only the three public characters reach the server, and the room name made from them gives no way to test guesses at the password.
  • Your licence code, in readable form. It becomes a one-way fingerprint, under a secret only the server holds, before it touches any storage key or log line. Somebody holding a copy of our database could not confirm whether a guessed code was real.
  • Your PC's name. Windows machine names often contain the owner's name, so it is never sent; your phone and our server see the word "PC". Your screen resolution is rounded off for the same reason, because an unusual one is a fingerprint.

What it does see

  • Both devices' IP addresses, because it cannot answer a request without one. On the metered paths it fingerprints rather than stores them.
  • Which room, and when. That two devices met, at what time, for how long, and whether one is online now.
  • The setup messages, in readable form. They are relayed byte for byte, with no parsing or inspection anywhere on that path, but "relayed unchanged" means the server could read them and we would rather say so. They hold the handshake values, the network addresses your devices offer each other, the certificate fingerprints, and the PC's display name if you set one. Never any media.

Everything the app sends us, in full

Five requests, and this is all of them:

  • The rendezvous connection, whose address carries the room name and whether this device is the PC or the phone.
  • A room claim: the room name and your licence code, which gets back a signed token proving your PC owns that room so a stranger cannot displace it.
  • A licence check: the licence code and one word for the device type, "pc" or "phone". No machine identifier, no operating system, no version.
  • A request for relay servers, only when your devices cannot reach each other directly, and only ever to our own switchboard.
  • An update check at startup and once a day, identifying itself as the bare word "PCTether". No version and no machine detail, because a richer string would be a fingerprint we would then be storing about our own users.

Tether is free while it is in early access. The licence code switches remote access on; nothing is charged for it right now.

No analytics, and we checked rather than assumed

Neither app contains an analytics, telemetry or crash-reporting product. We searched both codebases for every common vendor by name and found none, then ran the same search for a third-party service we do use. It found it, so the search works.

5. What is stored, and where

On your PC

  • The reconnect key for each paired phone, encrypted with your Windows login, so a copy taken to another machine or account decrypts to nothing. If that encryption is ever unavailable the app refuses to save the key at all, and you re-pair on the next launch.
  • Your licence code, as plain text in the app's settings file. Anyone who can read your Windows user profile can read it.
  • Connection statistics with no addresses in them: what kind of route each connection used, never where the other end was.
  • Relay use as monthly totals, kept for twelve months and sent nowhere.
  • An error log with addresses, pairing codes and your Windows username stripped out before anything is written.
  • A line each time a saved phone login looked wrong, naming which phone and what the PC did about it. No addresses. Versions before August 2026 recorded one, and the app removes those the next time you open it.

On your phone

  • The reconnect key, in Android's Keystore, the same place the system offers any app for credentials. On phones with a secure chip it is backed by hardware. We do not check which kind your phone gave us, so we are not going to claim the stronger one.
  • Your licence code, the PC's address, its name and its certificate fingerprint, in the app's ordinary settings rather than that vault. Readable only to Tether, and kept out of device backups.

On our servers

  • Your licence code, in readable form on our servers, where it is the name of its own record. Your apps send it to us when they check your access.
  • When a code first connected, and the kind of device, so a code being passed around can be noticed.
  • Setup messages, briefly, and only when one device arrives before the other. Deleted the moment the second connects, or five minutes after the first stops waiting. Everything after that is passed straight through and never written down.
  • A short-lived note each time a device asks about the relay, which is every time the app starts and not only when the relay is used: the time, and a one-way fingerprint of the address it asked from, which cannot be turned back into an address. It counts how many devices share one licence, and it is deleted about two and a half hours later.
  • What our code check answered, with nobody named in it: the moment, one word for the answer, and whether our server replied normally. No code, no address and no device go with it, so the line itself names nobody. It is there so we can tell whether somebody was turned away by a code that did not work, which nothing else we keep can answer. Deleted after ninety days.
  • Your email address, if you joined the waiting list, in two places: the list itself, and the label on the code we send you. Both are deleted the first time your code is used, or within a day of it running out, which for a code nobody ever uses is within ninety days of the day we send it. The cleaner only acts on a code with an end date that has passed, so if yours has no end date, or we have switched it off, ask us and we will remove yours.

Two copies outlive that deletion. The email that carried your code sits with the service that delivered it, under their retention rather than ours, and our database keeps a restore point for up to thirty days.

Licence codes never appear in logs, on any path.

On this website

Nothing is kept in your browser, with one exception: after a purchase the thank-you page holds your licence link for that tab only, so a refresh cannot lose a code you have just been given. It goes when the tab closes.

The same ground, stated as a legal commitment rather than an engineering description, is in the privacy policy.

6. What this does not protect you from

Anyone who can see the code can pair

A glance over your shoulder, a photo of your monitor, a camera behind you. Any of those is a complete break of first-time pairing. The maths protects the code from everyone on the network and does nothing about a person in the room.

There is no "add a device" mode

While the PC app is running it accepts a brand-new pairing attempt at any moment, and home-network access is on by default once you have paired one phone, so a paired PC keeps a pairing listener open on your Wi-Fi indefinitely. Guessing still takes years, so this is exposure rather than a break, but a stranger on your network gets unlimited throttled attempts and you are never told. There should be a switch that closes the door. There is not one yet.

Anyone who controls your PC has already won

Malicious software running as you can read the stored reconnect key and tamper with a live session, because the key is sealed to your account so that you can use it. If your PC is compromised, Tether's encryption is not what stands between you and the attacker.

An unlocked, stolen phone is full control of your PC

The key is in secure storage and the app can sit behind your fingerprint or PIN, but neither helps if someone is handed your phone already unlocked.

And there is no way to cut it off from somewhere else. The only way to remove a phone's access is to go to the PC and forget it there. We cannot do it for you, because there is no account to sign into, and that is the cost of the privacy choice. An unused key expires by itself after 180 days, chosen so a real owner back from a long trip is not locked out, so a stolen phone left switched off is still paired six months later. If you cannot get to your PC, the honest advice is to keep it turned off until you can.

We can see who connected to whom, and when

Both IP addresses, which room, the timing, whether you are online. Not your screen, your keystrokes or your files. But "cannot see your screen" is not "cannot see that you connected", and the second one is not true. Hiding the fact of the connection itself is not something Tether does today.

Your internet provider can see you use Tether

The app connects to our switchboard at startup and checks for updates once a day. The contents are encrypted; the destination and timing are visible to anyone watching your network. No software can change that, and the daily check is in effect a once-a-day signal that this PC runs Tether.

We do not choose the session's encryption algorithm

DTLS-SRTP is the mechanism and that is verifiable. The specific cipher is negotiated between the two WebRTC implementations at run time and nothing in our code pins one.

The Windows installer is not signed

Every Windows user clicks through an "unknown publisher" warning to install software that takes their screen, keyboard and mouse. That is exactly the warning a person should heed, and we are asking them to ignore it. It is the single worst thing about how Tether reaches you today, worse than anything in the encryption, and a code-signing certificate is the fix.

Signing you in from your phone means a Windows service that can reach your login screen

Tether can sign you into a locked PC from your phone. That only works if something on the PC is allowed to type into the Windows sign-in screen, which is a place a normal program is deliberately locked out of. So the feature runs as a Windows service at the highest level the system has, and while it is on it can see and type into your login screen. That is the whole point of it, and it is also the honest cost.

It is off until you turn it on. It is not in the installer, there is no such service on a fresh install, and you switch it on yourself in Settings with a prompt that asks for administrator permission. If you installed the version that needs no administrator, this part is not on your computer at all: those bytes are left out of that download rather than switched off, so there is nothing there to turn on and Settings says so. A service running that high is a larger target than the app around it, and anyone who already had administrator control of your PC could lean on it, though by then they have already won. We keep it off by default, we make you choose it, and we name it here because a page that lists a switched-off push component should certainly list a switched-on service that can watch you log in.

Licence checking is not a security control

The apps check their own code, with a fourteen-day offline grace so a network blip does not lock you out mid-session. A modified copy of the app is not stopped by that layer. It sits on top of the encryption and never touches it.

A stranger can block a first-time pairing over the internet

Meeting rooms are named from only the three public characters, and about an hour of effort covers that whole space, so somebody could occupy the room your PC is waiting in and stop a new pairing completing. Our server pushes back on clients that dial many rooms, and a PC already holding a room cannot be evicted, so it is a nuisance rather than a break: occupying a room never reveals the password, which lives in the other half of the code. Already-paired phones are unaffected.

Certificate pinning does not work the same way on both paths

On your home network the phone checks the PC's certificate directly against a copy it remembers. Over the internet it trusts our switchboard's ordinary web certificate for that connection and establishes the PC's identity separately inside the messages, bound to the fingerprints in section 3. The guarantee holds, by a different mechanism than "pinning everywhere".

One asymmetry we have found and not yet fixed

The phone plays incoming sound from the far end before that end has finished proving who it is. Video and remote control are correctly held back. The reach is narrow, because a legitimate PC attaches no audio until after it has verified the phone, so it only matters against an already-hostile far end. It is still an inconsistency, we found it in our own audit, and it is listed here rather than after the release that closes it.

The phone does not meet one requirement the pairing standard sets

RFC 9382 says the curve arithmetic must take the same time whatever the secret is, so that timing it tells you nothing. The library the phone uses does not guarantee that. The exposure is narrow (precise timing needed, the secret lives for seconds, guessing is throttled) and we accepted it knowingly, but it is a stated "must" we do not meet.

A dormant Google push component ships inside the PC app

The installed app contains a file that would send notifications through Google's push service. Nothing runs it, nothing is connected to it, and no data goes to Google today. It is an unfinished feature. A page that tells you which servers the app talks to should also name the ones sitting in the binary switched off.

A disabled analytics tag exists in our source, but not in the page you receive

Our own copy of the homepage keeps a Cloudflare analytics snippet commented out, with a placeholder where a token would go. It has never run, and since 3 August 2026 every comment is stripped from the files the site serves, so it is not in the page your browser downloads. Check with View Source. We name it anyway, because it is one line away from being switched on at our end.

The comment-stripping was not tidiness. Comments are invisible on the page and fully visible in the source, which is exactly what stops anyone noticing them; ours had collected developer notes and internal document names. Rather than police the wording, we stopped shipping comments.

Cloudflare and Stripe are unavoidable third parties

Our switchboard runs on Cloudflare and payments run through Stripe, and everything on this page stops at the edge of our own code. One specific consequence: the room name travels inside the web address of the rendezvous connection, and web addresses are the part of a request edge logs typically capture. Nothing in our code writes it down. We do not control what theirs does.

Nothing here protects you from someone at your unlocked machine

Your licence code is readable text on disk, the settings file is ordinary text, and the queue of files waiting to send is a plain list of paths. The reconnect keys resist being copied to another computer, but not somebody sitting at yours.

7. For the technically minded

The primitives, named exactly. Anything not on this list is not something we claim.

Pairing handshake
RFC 9382 SPAKE2, ciphersuite P256-SHA256-HKDF-HMAC, protocol profile string tether-pin-pake-v1. The two ends run different stacks, both version-pinned exactly. PC: group operations from @noble/curves 2.2.0, HKDF and HMAC from Node's own crypto. Phone: group operations from pointycastle 4.0.0 (secp256r1), HKDF and HMAC from cryptography_plus. The RFC's M and N seed points are embedded uncompressed as nothing-up-my-sleeve constants.

One known shortfall, on the phone. RFC 9382 §7 says the scalar multiplication MUST be constant-time; pointycastle's is not. A library that takes a measurably different amount of time depending on the secret can, in theory, leak that secret to something able to measure it precisely. We judged the practical risk small (the secrets exist for seconds and guessing is throttled), but it is a stated MUST that we do not currently meet. Section 6 says so rather than leaving it in a source comment where only a developer would find it.
Password derivation
The code is turned into a scalar and never sent: w = OS2IP(HKDF-SHA256(ikm = utf8(code), salt = empty, info = "tether-pin-pake-v1|w", L = 40)) mod n Forty bytes of output gives 64 bits of headroom over the curve order, which removes modulo bias. Only 65-byte curve points and 32-byte HMACs cross the wire.
Code layout
8 characters over a 32-symbol base32 alphabet (2-9, A-Z, less 0/O/1/I). Characters 1-3 are public; characters 4-8 are the SPAKE2 password. 325 = 33,554,432, about 25 bits.
Rendezvous room
Derived from the PUBLIC slice only, so it is not an offline oracle for the password: roomId = base32(HKDF-SHA256(ikm = utf8(Cpub), salt = empty, info = "tether-room-v1", L = 5)) The result is 8 base32 characters.
MITM binding
Both DTLS certificate fingerprints are bound into the confirmation keys, in a fixed PC-then-phone order: AAD = utf8(fpPC) ‖ 0x00 ‖ utf8(fpPhone)
KcA ‖ KcB = HKDF-SHA256(ikm = Ka, salt = empty, info = "ConfirmationKeys" ‖ AAD, 32)
cA = HMAC-SHA256(KcA, TT)
cB = HMAC-SHA256(KcB, TT)
A relay presenting its own certificate changes a fingerprint, so both MACs fail.
Fingerprint parsing
Line-anchored extraction of every a=fingerprint line, canonicalised; a value is returned only if the set collapses to exactly one. More than one distinct fingerprint aborts the pairing rather than picking a winner.
Pairing key
Derived on both sides and never transmitted in any form: pairingKey = HKDF-SHA256(ikm = Ke, salt = empty, info = "tether-pin-pake-v1|pairing-key", L = 32) Here Ke is the first 16 bytes of SHA-256(transcript).
Reconnect proof
Sent on every reconnection in place of the code: HMAC-SHA256(pairingKey, utf8(role) ‖ 0x00 ‖ nonceH ‖ nonceP ‖ 0x00 ‖ utf8(fpPC) ‖ 0x00 ‖ utf8(fpPhone)) The role is one of the anti-reflection literals "phone" or "PC", and both nonces are fixed at 16 bytes. Fresh nonces make a captured proof replay-dead; the fingerprints make it die if the media path was re-terminated.
Key ratchet
Applied on every reconnect. A proof is accepted under the previous, current or next generation: a two-step grace plus a bounded one-step forward catch-up, so a crash between advancing and saving never strands the owner. A captured key therefore survives one further legitimate reconnect and dies on the second, and the out-of-step use raises a possible-copy signal: key(n+1) = HKDF-SHA256(ikm = key(n), salt = empty, info = "tether-reconnect-v1|ratchet|" ‖ uint32be(n+1), 32)
Certificate pin
Checked as an exact SHA-256 of the certificate's DER bytes (no CA path, no hostname check) on the direct/LAN leg only. A mismatch raises a fingerprint-mismatch error and there is no plaintext leg on that path to fall back to, so a downgrade is structurally impossible rather than forbidden by policy. The pin is accepted only out-of-band via the QR code's fingerprint field, or in-band carried by an authentication tag: fpMac = HMAC-SHA256(master, utf8("tls-fp") ‖ 0x00 ‖ utf8(fpHex))
master = HKDF-SHA256(ikm = Ke, salt = empty, info = "tether-pin-pake-v1|master", 32)
Session transport
One RTCPeerConnection: a sendonly video transceiver, a sendonly audio transceiver, and three SCTP data channels: control (ordered, reliable), file (ordered, reliable) and input (ordered, maxRetransmits: 0). Data channels ride SCTP inside the same DTLS association as the media. DTLS-SRTP; no cipher suite is pinned anywhere in our source.
Pre-auth isolation
An unverified peer negotiates on a second, isolated peer connection with trackless sendonly transceivers. DTLS still completes, so the fingerprints exist to bind into the confirmation, but no media exists to leak. replaceTrack() fills the senders only after the host has verified the MAC.
Throttles
Per-IP: 5 failures, 30-second cooldown. Global sliding window: 10 failures per 60 seconds, 45-second cooldown. Both evaluated before any curve arithmetic runs.
Network perimeter
Binds 127.0.0.1 always, and concrete LAN IPv4 addresses only when LAN exposure is on. Never 0.0.0.0. Any WebSocket upgrade carrying an Origin header is refused with 403 before a socket exists, which closes browser-driven DNS rebinding.
At rest, on the PC
Electron safeStorage, which is Windows DPAPI, bound to the logged-in account. Fail-closed: if sealing is unavailable the store writes nothing and keeps trust in memory for that session only. The device identifier is persisted as SHA-256 only.
At rest, on the phone
Android Keystore-backed secure storage for the reconnect credential and the device identifier. Everything else the app remembers, including the PC's address, its display name, its certificate pin and the licence code, is app-private SharedPreferences rather than Keystore. The app is built with allowBackup="false", so none of it leaves the device in a backup.
At rest, on the server
Licence codes are stored and logged only as a domain-separated keyed HMAC, truncated, under a server secret. That was chosen over a plain hash specifically so that an attacker holding a database dump plus a candidate code could not recompute the value and confirm the code was live. Client IPs on the metered path are fingerprinted the same way.

If you find something on this page that is wrong, or something we have left out, write to support@pctether.com. A correction to this page is worth more to us than a compliment about it.

8. Reporting a security problem

Found a weakness in PC Tether? We want to hear about it. A false alarm beats a missed one.

Where to send it

support@pctether.com. A person reads it. Start the subject with Security so it isn't treated as ordinary support.

What helps most

  • What you found, and what an attacker could do with it.
  • Steps to reproduce it, plus your Windows/Android and app versions (app version is at the bottom of the PC window).
  • A fix, if you have one. Welcome, never required.

What we will do

  • Reply within five working days. No answer by then? Resend. It went astray.
  • Tell you straight whether we agree it's a problem, and if not, why.
  • Keep you posted, and tell you when it's fixed.
  • Credit you in the release notes, or not. Your call.

Please don't

  • Test against anyone else's computer, phone, or code. Use your own.
  • Flood or denial-of-service the relay. It's small and you'll just take it down for real users.
  • Go public before a fix ships, or 90 days, whichever is first.

Our side of it

If you follow the two lists above and report in good faith, we will not pursue legal action against you, and we will not ask anyone else to. We treat that kind of research as help, because it is. If you are not sure whether something is in bounds, ask first and we will tell you.

We are honest about one thing up front: there is no bug bounty and no payment. Tether earns nothing today, so there is nothing to pay from. What we can offer is a fast, straight answer from the person who wrote the code, and public credit if you want it.

Machine-readable version of this section: /.well-known/security.txt.