Absolute Privacy for I2P Services: Encrypted LeaseSet
The core principle of anonymity in I2P is that the location of a hidden service remains unknown. Every hidden service—such as a website or a user visiting it—interacts with other resources exclusively through anonymizing tunnels. These tunnels are built through the routers of network participants, just as other users build tunnels through your router. This model creates numerous direct connections between I2P routers, making it impossible to determine on which router a tunnel started or ended: thousands of simultaneous encrypted connections prevent such identification.
To connect to any hidden service, you need to obtain its LeaseSet, which contains information about inbound tunnels and cryptographic keys. All server endpoints waiting for connections publish their LeaseSets on floodfills—special routers that act as directories or bulletin boards. Although a floodfill only receives information about the first nodes of inbound tunnels and cryptographic keys (meaning there’s no compromising information in the LeaseSet), the I2P architecture provides for the use of encrypted LeaseSets. This hides the existence of the endpoint (also called a “hidden service” or “destination”) from potential monitoring on floodfills.
The identifier of an unencrypted LeaseSet is simply the internal network address of the hidden resource, minus the “.b32.i2p” ending. This allows floodfill operators to see the addresses of resources published on their routers in plain text. If you’ve set up a private resource in I2P and don’t want anyone else to accidentally discover it, an encrypted LeaseSet is made for you!
Unencrypted LeaseSet on Floodfill
Hiding the LeaseSet identifier is called “blinding” in English terminology. That’s where the term “bb32” comes from—blinded-b32. The “b32” in all I2P domains refers to the base32 encoding used for the domain information. Note that “bb32” is just a term; it’s not actually used in addresses.
- Regular:
http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p
- Encrypted:
http://tojbxbveijj5c6ql25bifzdfh5xm2idc36cbffrmdfovuykgtjd2yfuk.b32.i2p
The bb32-type LeaseSet identifier (visible to the floodfill) does not correspond to the actual address, so the floodfill operator cannot determine the real name of the resource published on their router. Also, you can’t assign a short domain in the “i2p” zone to a bb32-type address. The only way to access such a hidden service is to have its full address string. When given a bb32 address, the I2P router requests the corresponding encrypted LeaseSet from the floodfill and then decrypts its contents using additional information encoded in the domain.
The domain name of a regular endpoint consists entirely of the hash of the full address (a set of cryptographic keys that comes with the LeaseSet), while the address with an encrypted LeaseSet is the public signing key of the hidden resource, plus three bytes of special information: flags, signature type, and encrypted signature type.
You can read about the cryptographic details of blinding (hiding the LeaseSet identifier) and encrypting its contents in the official documentation. According to the documentation, two signature types are supported in encrypted LeaseSets: EDDSA_SHA512_ED25519 (type 7) and REDDSA_SHA512_ED25519 (type 11), but it is strongly recommended to use only the second one. In i2pd, the non-recommended option isn’t implemented at all, as it’s considered practically pointless.
This is because, first, signature type 11 is algorithmically more optimal for use in encrypted LeaseSets. Second, signature type 7 is used by default and allows for the accidental use of an existing address with an encrypted LeaseSet. Theoretically, this is a vulnerability, as it allows a malicious floodfill to reveal another encrypted LeaseSet for a service that previously used a regular LeaseSet with the same signing key. This is possible because the blinding algorithm can be reproduced if the full endpoint address included in the LeaseSet is known in advance. The idea is that a user who manually sets signature type 11 will also specify the required LeaseSet type, preventing any leaks.
Minimal Tunnel Configuration for a bb32 Endpoint
The minimal configuration for a bb32-type endpoint (sometimes called b33, though this is not logical) looks like this (the last two lines are crucial):
[SUPER-HIDDEN-SERVICE] type = server host = 127.0.0.1 port = 8080 inport = 80 keys = site.dat signaturetype = 11 i2cp.leaseSetType = 5
Earlier, we mentioned flags contained in the first byte of the address with an encrypted LeaseSet. The main flag of interest here is the authorization flag. It’s configured via the additional parameter i2cp.leaseSetAuthType
. In short, this allows you to make access to a private resource even more controlled by creating a list of keys or passphrases for each user. If needed, you can remove a specific identifier from the list, after which that user will no longer receive the LeaseSet and, therefore, will lose access to the resource. For more details, see the documentation (parameters: i2cp.leaseSetPrivKey
, i2cp.leaseSetClient.dh.nnn
, i2cp.leaseSetClient.psk.nnn
).
The original article was published on the ITSOFT data center blog.