Filename: 371-dummy-tap-keys.md
Title: Use dummy TAP keys for backward compatibility
Author: Nick Mathewson
Created: 4 November 2026
Status: Closed
Introduction
This proposal documents an already-merged feature in Tor 0.4.9.16.
It builds ideas from proposal 350.
For background: TAP keys are obsolete 1024-bit RSA keys that were once used for circuit extension. Tor 0.2.4 added support for ntor. TAP keys were still used for some circuit hops (intro points and rendezvous points) in v2 onion services. After v2 onion services were removed, we removed client and relay support for TAP keys, and allowed the keys to be absent from microdescriptors.
In consensus method 37, when we removed TAP keys from microdescriptors,
and added the Microdsesc=3 capability to the required-protocols list.
But we encountered several bugs:
- Our
required-protocolscode did not remember the consensus before deciding to exit because of its required protocols. (tor#41466) - Our code to prevent clients from re-fetching unusable microdescriptors did not actually prevent them from doing so. (tor#41467)
Because of the first bug,
we didn't actually disable all the old clients
that get restarted by systemd whenever they exit.
So we needed to remove Microdesc=3 from required-protocols.
Because of the second bug, we need to re-add TAP keys to microdescriptors. But we did not want to use relays' actual TAP keys, for two reasons:
- Not all relays have TAP keys; Arti relays will not.
- One of the benefits of removing TAP keys was to reduce the size of microdescriptor downloads; putting them back would lose that benefit.
Behavior change
We introduce a new consensus method, "38".
When generating microdescriptors using this consensus method,
authorities set the TAP onion-key of each microdescriptor
to the following value:
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAKQZ1kmo8X2H9dJeAiGmm2Oi0XMVYKXrFMnG9g3YnoTWO1nr03lJPvnM
JXj4hxx9XBHKkwr4bG2KeT8umxTVd2r/LOUxkgu/0nizaCs4tBqsauH6hL81tXSi
0vxYhR7Vvtt4K3idvlMvzDit+l8LseT4foqz2DDAAOO2noy6LjCvAgMBAAE=
-----END RSA PUBLIC KEY-----";
This public key was generated by a relay in a chutney network.
The corresponding private key is
-----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQCkGdZJqPF9h/XSXgIhpptjotFzFWCl6xTJxvYN2J6E1jtZ69N5 ST75zCV4+IccfVwRypMK+Gxtink/LpsU1Xdq/yzlMZILv9J4s2grOLQarGrh+oS/ NbV0otL8WIUe1b7beCt4nb5TL8w4rfpfC7Hk+H6Ks9gwwADjtp6Mui4wrwIDAQAB AoGBAI1tfxNouQf5P1EYmDmsP0u1rVHD4NHeMsJb6P+x65yMjgZHirCDAfWDjeAe QUO6frkOn3/a7ofRygE8B4gDGbEKAlY+D6QbTicOGuzv4HIapGDyA8uWMG/p5ZR4 7iCOwrClx4adAseUQYkcQZMicgtBB34LHX+8gHyEA6qRtNSxAkEAzirJgV2QoJBV UBit18r3cfGn9voVNs3xgYmbSJmSq81BTGp9jPZ1RCa8+W8Jlh65bXSg7W0yZTOF 5erh90wA3QJBAMvEE4vYsuAoKCMBMSq3AAZUlqLz1ghi1GwE+WdLF9ulJu/FYmuc 9djSoQRduOsmRo0stU4X6Rat0PRaXeBNOPsCQQCMJvolP336KSRV9vD3KbtdcnJE q22QfCAZd3pguEXFFRu23w3KriC527vLtXhG3Uwg5JAh14HS2lvEGRDUFI7hAkBF Ffm6lIIxVewl0iWlYd50RwG7xghvV3LGHPmid+di5R/Kc5Xm/pSsKt3E6THlKFkL THk8PQceVVhfQLRLdGM5AkEAsG4VW/rqLRB22Dsv23ReiCqi9S95aLgRExCk/LR/ PcBG6JLzkBUzziksA0c9olarFXdwFbPU0YR+DtyHutunxQ== -----END RSA PRIVATE KEY-----We include the private key here to prove that there is "nothing up our sleeve".
The alternatives would be:
- generating a keypair, throwing away the private key, and saying "trust us, we threw it away".
- doing some kind of elaborate MPC ceremony to generate a public key with unknown public key.
The former alternative would be suspicious. The latter alternative would be somewhat pointless, given the ever-falling security of RSA1024.
Analysis
Download size
When clients download microdescriptors, they usually fetch more than one at a time. If all microdescriptors have the same TAP key, we expect the compression to effectively "hide" all but the first.
(In effect, everything from onion-key\n through ntor-onion-key will be
a fixed string at the start of each microdescriptor.)
Security analysis
We are now distributing a public key whose private key is also publicly known. Anything encrypted to this public key is effectively not encrypted at all.
This ought to make us pause, to make sure that we aren't actually breaking anything. Even though the clients using TAP are all obsolete, we should nonetheless ensure that they are not common.
First, what could an adversay do if a client tried to use this TAP key? If the client tries to use this TAP key to extend a circuit from a hostile relay to some other relay, the hostile relay can impersonate that relay. If the client continues using TAP, the hostile relay can capture the whole circuit.
Second, when were TAP keys used?
- In versions before 0.2.4, they were used for all circuit extensions, since these versions did not support ntor.
- In versions 0.2.4 through 0.2.9, they were used for all circuit extensions when the relay did not support ntor. (This hole was closed in tor#19163.)
- Up until v2 onion services were removed in 0.4.6.1-alpha, they were used to extend to the final hop of service→RP and client→IP v2 onion service circuits if that hop was not listed in the consensus.
So, considering each case:
-
Tor versions before 0.2.4 will not run on the current network without substantial reconfiguration. Of the 9 authorities that were listed, only 3 are still present with the same keys. (See appendix.) These versions may fail to connect for other reasons too; I haven't checked.
-
All microdescriptors include an ntor onion key, so the TAP code in 0.2.4 through 0.2.9 will not trigger. Furthermore, we now list
FlowCtrl=1as a required protocol: 0.2.9 through 0.4.0 will always exit because of this. (0.2.9 introducedrequired-client-protocols; 0.4.1 introduced authenticated SENDMEs.) -
Tor removed v2 onion service support completely in 0.4.6: honest relays will never accept v2 onion service requests. In order to mount an attack here, an attacker would need an obsolete client to be running and trying to serve or connect to a v2 onion service. The attacker would need to run the relay that got chosen as the HSDir for the onion service. The attacker would need to actually be the IP and the RP, since an honest relay would not act as an IP or an RP for a v2 onion service. (The attacker cannot use TAP to impersonate an IP to the service, or the RP to the client, since those parties use ntor to connect to the those relays.) The attacker would need also control the relays before the IP and the RP on the relevant circuits, since otherwise any attempted TAP handshake would be rejected. Therefore, in order to have any v2 service running such that the attacker could actually MITM the RP or IP, the attacker would already need to be running the IP and RP. There is no point in running an MITM attack against your own relays, so this is not an attack at all.
So the only vulnerable Tor clients (if there are any!) are those running versions before 0.2.4 who have reconfigured their authority set in order to stay compatible with the current network. (I posit that there are quite few of these: updating your torrc with a newer authority list is harder and worse than just upgrading to a secure version of Tor.) Further, there are numerous known high-severity security issues in 0.2.3 and earlier, and in the versions of OpenSSL that they support: anybody who is running such an ancient version of Tor (released in 2012) and hand-editing its authority list is already somebody who does not take their security seriously at all.
Therefore, we conclude that our new behavior is safe.
(See tor!1072 for earlier discussion.)
Appendix: Our current directory authorities and their keys
This information was annoying to chase down, so I'll reproduce it here:
These are our authorities as of 4 November 2026:
| Authority | Current key generated |
|---|---|
| dizum | 2008 |
| gabelmoo | 2010 |
| maatuska | 2010 |
| longclaw | 2014 |
| dannenberg | 2015 |
| bastet | 2017 |
| moria1 | 2022 |
| faravahar | 2024 |
| tor26 | 2024 |
Danenberg's key rotation on 18 November 2015 is the one 0.2.3 clients (and earlier) do not have.