Provided by: syncthing_1.27.2~ds4-1ubuntu0.24.04.2_amd64 bug

NAME

       syncthing-device-ids - Understanding Device IDs

       Every  device  is identified by a device ID. The device ID is used for address resolution, authentication
       and authorization. The term “device ID” could interchangeably have been “key ID” since the device ID is a
       direct property of the public key in use.

KEYS

       To  understand  device IDs we need to look at the underlying mechanisms. At first startup, Syncthing will
       create a public/private keypair.

       Currently this is a 384 bit ECDSA key (3072 bit RSA prior to v0.12.5, which is what is used as an example
       in  this  article).  The  keys  are  saved  in  the  form  of the 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 enables the use of the keys in a standard TLS exchange.

       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

       We  can  see  here  that  the  certificate is little more than a container for the public key; the serial
       number is zero and the Issuer and Subject are both “syncthing” where a qualified name might otherwise  be
       expected.

       An  advanced  user  could replace the key.pem and cert.pem files with a keypair generated directly by the
       openssl utility or other mechanism.

DEVICE IDS

       To form a device ID the SHA-256 hash of the certificate data in DER form is calculated.  This  means  the
       hash covers all information under the Certificate: section above.

       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. This  becomes  52  characters  in
       practice,  but 52 characters of base32 would decode to 260 bits which is not a whole number of bytes. The
       base32 encoding adds padding to 280 bits (the next multiple of both 5 and 8 bits)  so  the  resulting  ID
       looks something like:

          MFZWI3DBONSGYYLTMRWGC43ENRQXGZDMMFZWI3DBONSGYYLTMRWA====

       The  padding  (====)  is  stripped  away,  the  device  ID  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, resulting in the final value:

          MFZWI3D-BONSGYC-YLTMRWG-C43ENR5-QXGZDMM-FZWI3DP-BONSGYY-LTMRWAD

   Connection Establishment
       Now  we  know what device IDs are, here’s how they are used in Syncthing. When you add a device ID to the
       configuration, Syncthing will attempt to connect to that device. The first thing we need to 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 have 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 will be queried for an address.

       Once  we  have an address and port a TCP connection is established and a TLS handshake performed. As part
       of the handshake both devices present their certificates. Once the handshake has completed and  the  peer
       certificate is known, the following steps are performed:

       1. Calculate the remote device ID by processing the received certificate as above.

       2. 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.

       3. Verify the remote device ID against the configuration. If it is not a device ID we  are  expecting  to
          talk to, drop the connection.

       4. Verify the certificate CommonName against the configuration. By default, we expect it to be syncthing,
          but when using custom certificates this can be changed.

       5. If everything checks out so far, accept the connection.

AN ASIDE ABOUT COLLISIONS

       The SHA-256 hash is cryptographically collision resistant. This means that there is no way that  we  know
       of to create two different messages with the same hash.

       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.

       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 that we are 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.

       Note also that it’s not good enough to find a random blob of bits that happen 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.

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. This means that any device can in
       theory announce itself for any device ID and potentially receive connections for  that  device  from  the
       local network.

   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.

       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  (“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, a 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-2019, The Syncthing Authors