SYNCTHING-DEVICE-IDS(7)
π NAME π
syncthing-device-ids β okay bestie, this whole page is about Understanding Device IDs π
Every device is identified by a device ID. That ID is literally the whole personality of the machine β it's used for address resolution, authentication and authorization. And honestly? "device ID" could just as well have been called "key ID", because the device ID is a direct property of the public key in use. No cap. π
β¨ KEYS β¨
So to actually get device IDs, we gotta look under the hood first. At first startup, Syncthing will create a public/private keypair. Iconic behavior, honestly.
Right now that's a 256 bit Ed25519 key (it was 384 bit ECDSA prior to v2.0.0, and 3072 bit RSA prior to v0.12.5 β and that RSA one is what's used as the example in this article, so don't come for me π«Ά). The keys get saved as a private key (key.pem) and a self signed certificate (cert.pem). The self-signing part doesn't actually add any security or functionality as far as Syncthing is concerned, but it does enable the use of the keys in a standard TLS exchange. It's giving β¨convenienceβ¨.
The typical certificate will look something like this, inspected with openssl x509:
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 0 (0x0)
Signature Algorithm: sha1WithRSAEncryption
Issuer: CN=syncthing
Validity
Not Before: Mar 30 21:10:52 2014 GMT
Not After : Dec 31 23:59:59 2049 GMT
Subject: CN=syncthing
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (3072 bit)
Modulus (3072 bit):
00:da:83:8a:c0:95:af:0a:42:af:43:74:65:29:f2:
30:e3:b9:12:d2:6b:70:93:da:0b:7b:8a:1e:e5:79:
...
99:09:4c:a9:7b:ba:4a:6a:8b:3b:e6:e7:c7:2c:00:
90:aa:bc:ad:94:e7:80:95:d2:1b
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Basic Constraints: critical
CA:FALSE
Signature Algorithm: sha1WithRSAEncryption
68:72:43:8b:83:61:09:68:f0:ef:f0:43:b7:30:a6:73:1e:a8:
d9:24:6c:2d:b4:bc:c9:e8:3e:0b:1e:3c:cc:7a:b2:c8:f1:1d:
...
88:7e:e2:61:aa:4c:02:e3:64:b0:da:70:3a:cd:1c:3d:86:db:
df:54:b9:4e:be:1b
See how the certificate is basically just a container for the public key? The serial number is zero, and both Issuer and Subject are syncthing where a qualified name might otherwise be expected. Lowkey minimalist queen π
An advanced user could swap out the key.pem and cert.pem files with a keypair generated directly by the openssl utility or some other mechanism. Go off, I guess π
π¦ DEVICE IDS π¦
To form a device ID, the SHA-256 hash of the certificate data in DER form gets calculated. That means the hash covers all the information under the Certificate: section above. Everything. The whole vibe. π
The hashing results in a 256 bit hash, which we encode using base32. Base32 encodes five bits per character, so we need 256 / 5 = 51.2 characters to encode the device ID. In practice that becomes 52 characters β but 52 characters of base32 would decode to 260 bits, which is not a whole number of bytes π. So the base32 encoding adds padding to 280 bits (that's the next multiple of both 5 and 8 bits), and the resulting ID looks something like:
MFZWI3DBONSGYYLTMRWGC43ENRQXGZDMMFZWI3DBONSGYYLTMRWA====
The padding (====) gets stripped away, the device ID is split into four groups, and check digits (https://forum.syncthing.net/t/v0-9-0-new-node-id-format/478) are added for each group. For presentation purposes the device ID is grouped with dashes, giving us the final value:
MFZWI3D-BONSGYC-YLTMRWG-C43ENR5-QXGZDMM-FZWI3DP-BONSGYY-LTMRWAD
π Connection Establishment π
Now that we know what device IDs are, here's how Syncthing actually uses them. When you add a device ID to the configuration, Syncthing will attempt to connect to that device. First thing we gotta do is figure out the IP and port to connect to. There are three possibilities here:
- The IP and port can be set statically in the configuration. The IP can equally well be a host name, so if you've got a static IP or a dynamic DNS setup, this might be a good option. π«Ά
- Using local discovery, if enabled. Every Syncthing instance on a LAN periodically broadcasts information about itself (device ID, address, port number). If we've seen one of these broadcasts for a given device ID, that's where we try to connect. π‘
- Using global discovery, if enabled. Every Syncthing instance announces itself to the global discovery service (device ID and external port number β the internal address is not announced to the global server). If we don't have a static address and haven't seen any local announcements, the global discovery server gets queried for an address. π
Once we have an address and port, a TCP connection is established and a TLS handshake is performed. As part of that handshake, both devices present their certificates. Once the handshake has completed and the peer certificate is known, the following steps happen:
- Calculate the remote device ID by processing the received certificate as above.
- Weed out a few possible misconfigurations β i.e. if the device ID is that of the local device, or of a device we already have an active connection to. Drop the connection in these cases. π
- Verify the remote device ID against the configuration. If it's not a device ID we're expecting to talk to, drop the connection.
- Verify the certificate CommonName against the configuration. By default we expect it to be
syncthing, but when using custom certificates this can be changed. - If everything checks out so far, accept the connection. Slay β
π AN ASIDE ABOUT COLLISIONS π
The SHA-256 hash is cryptographically collision resistant. That means there is no way that we know of to create two different messages with the same hash. Periodt.
Now, you can argue that of course there are collisions β there's an infinite amount of inputs and a finite amount of outputs, so by definition there are infinitely many messages that result in the same hash. Fair. But bestie, hear me out:
I'm going to quote stack overflow (https://stackoverflow.com/questions/4014090/is-it-safe-to-ignore-the-possibility-of-sha-collisions-in-practice) here:
The usual answer goes thus: what is the probability that a rogue asteroid crashes on Earth within the next second, obliterating civilization-as-we- know-it, and killing off a few billion people ? It can be argued that any unlucky event with a probability lower than that is not actually very important. If we have a βperfectβ hash function with output size n, and we have p messages to hash (individual message length is not important), then probability of collision is about p2/2n+1 (this is an approximation which is valid for βsmallβ p, i.e. substantially smaller than 2n/2). For instance, with SHA-256 (n=256) and one billion messages (p=10^9) then the probability is about 4.3*10^-60. A mass-murderer space rock happens about once every 30 million years on average. This leads to a probability of such an event occurring in the next second to about 10^-15. Thatβs 45 orders of magnitude more probable than the SHA-256 collision. Briefly stated, if you find SHA-256 collisions scary then your priorities are wrong.
It's also worth noting that the property of SHA-256 we're using is not simply collision resistance but resistance to a preimage attack β i.e. even if you can find two messages that result in a hash collision, that doesn't help you attack Syncthing (or TLS in general). You need to create a message that hashes to exactly the hash that my certificate already has, or you won't get in. Good luck with that π
Also note: it's not good enough to find a random blob of bits that happens to have the same hash as my certificate. You need to create a valid DER-encoded, signed certificate that has the same hash as mine. The difficulty of this is staggeringly far beyond the already staggering difficulty of finding a SHA-256 collision. Like, not even the same universe of difficulty. π₯
π PROBLEMS AND VULNERABILITIES π
As far as I know, these are the issues or potential issues with the above mechanism.
π Discovery Spoofing π
Currently, the local discovery mechanism isn't protected by crypto. That means any device can in theory announce itself for any device ID and potentially receive connections for that device from the local network. Yeah. That's a thing. π¬
π Long Device IDs are Painful π
It's a mouthful to read over the phone, annoying to type into an SMS or even into a computer. And it needs to be done twice β once for each side. The way that this is genuinely a whole ordealβ¦
This isn't a vulnerability as such, but a user experience problem. There are various possible solutions:
- Use shorter device IDs with verification based on the full ID β like this: "You entered MFZWI3; I found and connected to a device with the ID MFZWI3-DBONSG-YYLTMR-WGC43E-NRQXGZ-DMMFZW-I3DBON-SGYYLT-MRWA, please confirm that this is correct".
- Use shorter device IDs with an out of band authentication, Γ la Bluetooth pairing. You enter a one time PIN into Syncthing and give that PIN plus a short device ID to another user. On initial connect, both sides verify that the other knows the correct PIN before accepting the connection. π§
π AUTHOR π
The Syncthing Authors
πΈ COPYRIGHT πΈ
2014-2026, The Syncthing Authors
okay that's the whole page bestie, hope you slayed π
this was syncthing-device-ids, version v2.1.0, dated Oct 07, 2026 β go forth and connect responsibly π¦β¨
π¦ where this page comes from
- arch rolling: syncthing 2.1.7-1 Β· MPL-2.0
- nixos 26.05: syncthing 2.1.7
- nixpkgs unstable: syncthing 2.1.7
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms