2

I have to communicate with more than two devices which have been working perfectly with Google NearbyAPI Connections. Now I need to secure the connection restricting the access to the cluster network. The API exposes a method to authenticate the devices, which is used with a token provided by the library, however, this token is intended to be authorized by two users in the UI. I need to do this programmatically, the user shouldn't do this.

There's a method to obtain a token to authenticate programatically, can be found in the docs, but it's not available in the library.

What I have tried to do:

As I don't see a way declared by the docs to do it without asking the user to accept the connection I had tried:

  • Putting a secret in the end of the endpoint

    id-secret So each device should decrypt the secret and validate the info matches the one registered and then accept the connection. But encrypting using AES consumes produce a long payload and this provokes that the devices are not discovered. I haven't tried with TDES as it supposes to provide a smaller payload, but I'm not sure if this will be the way to go.

  • Accepting the connection send the secret and if not valid disconnect. I don't see this a good option as the network will be expose to anyone and it can produce unstable behaviours.

What do you think might be a good approach to authenticate the devices? As the only entry point of information I see is the Endpoint.

Dani Mesejo
  • 61,499
  • 6
  • 49
  • 76

1 Answers1

2

At the moment, you'll have to accept the connection first and then do a challenge/response immediately afterwards. It's not the cleanest, but it'll still be secure.

Broadcasting identity

I'd recommend adding a unique ID to the endpoint name/info. eg. "12345:Will". This way, the device has a stable ID that you can reference. To make this even more secure, you can salt the ID. eg. "12:54321:Will", or "${salt}:${hashedId}:${name}". To resolve the hashed ID, you will have to loop over all the known IDs on your device and run sha(salt + id).limit(5) until one of them matches the hashId. This way, the advertisement changes every time the salt rotates and it's harder to track the device. Bonus points if you obuscate the name as well.

Securing the connection

Immediately accept the connection, without verifying the auth token. Do NOT send private information yet, as the connection is insecure. Both devices should start a timer (1~5sec), and issue a challenge to the other side. The challenge should include the auth token in some way. eg. privateKey.sign(authToken). You may also want to verify in both directions, so you can include the public key as well. eg. localPrivateKey.sign(sharedAuthToken + remotePublicKey). If both sides verify within the time limit, the connection can be considered secure.

Disclaimer: I work on Nearby Connections

Xlythe
  • 1,958
  • 1
  • 8
  • 12
  • We're exposing a 'raw authentication token' soon, that's much longer than the current token and made for this exact use case. If you use the short 5-char auth token, it's possible for a malicious device to repeatedly connect to 2 valid devices until both of its connections share the same 5-char auth token. From there, it can forward messages between the two to bypass the challenge/response. To avoid this, you either need to explicitly throttle connections by not accepting new connections for ~5sec, or wait for the longer token to make this attack much harder. – Xlythe Dec 12 '20 at 21:56
  • Thank you for your answer! I'll try your algorithm. Do you have any idea when the raw authentication token will be released? – alejandro-ordonez Dec 15 '20 at 16:24
  • Hopefully in January. The code is ready, so we're just waiting for someone to be freed up to push an updated SDK. – Xlythe Dec 15 '20 at 19:10