javaandroidgoogle-nearbygoogle-nearby-connections

How to authenticate programatically Connection API?


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:

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.


Solution

  • 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