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.
Advertisement
Answer
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