I'm using an Arduino Uno and a nRF8001 board from Adafruit to connect to an Android phone over bluetooth. I will be using it to lock and unlock a lock and I need to make sure only verified devices are able to initiate the locking and unlocking. I've searched around a bunch and I'm having trouble finding a clear example of what I should do to verify the connecting device. Currently I have the Arduino hooked up to the lock and whenever the Android phone connects, it is allowed to lock and unlock.

I'm pretty new to cryptography and some guidance would be helpful. From what I've read, it sounds like md5 hashing is both broken and not the correct solution for my problem. I've found SipHash and that seems to be the closest thing that I might need. The process I had in mind is as follows.

  1. Android tries to connect to the Arduino
  2. Arduino sees the request and sends a random string to the Android device
  3. The Android encrypts the string with a shared secret key and sends it back to the Arduino
  4. The Arduino decrypts the encrypted string and verifies it matches the original it sent if it does it it goes ahead and connects/continues with locking or unlocking.

Am I on the right track with SipHash and the process above? Is there a better more common way to do this? After searching around here I found some info here. It looks like I should worry about man-in-the-middle attacks and MAC spoofing. I would just check the MAC address as verification, but from what I remember, it is very easy to spoof MAC addresses. Any help would be appreciated.

1 Answer 1


You have the right idea, namely a shared secret that is never transmitted from one device to the other. If you do that, you should not need to worry about MAC addresses or MITM attacks. You are vulnerable only if attacker can get that shared secret.

Since the shared secret is the {ahem} key, you need to be confident that it cannot be generated independently. One way to do that is to generate it with a cryptographically secure pseudo-random number generator (CSPRNG). You might also consider using Diceware words, which are somewhat more human-friendly, but will need a longer string to get equal entropy.

Now, about the actual algorithm: SipHash is new to me, but a little reading tells me it's a keyed hash function. That is, it's not invertible, so step 4. will not work as you have written it.

If SipHash is a given, then Step 3 is "The Android hashes the string with a shared secret key and sends it back to the Arduino."

Step 4 is the real difference: "The Arduino computes the same hash and verifies it matches the hash received from Android; if it does it it goes ahead and connects/continues with locking or unlocking."

Alternatively, you could use symmetric encryption, such as AES. A little Googling around finds AES libraries for Arduino and I know that they exist for Android.

  • Is this really secure against man in the middle attack ? You could have a device(D) connected to both Arduino (A1) and Android (A2). D would get the random string from A1, forward it to A2. It would receive back the encrypted string from A2, forward it to A1, and here you go, D has full control over the door for this session. Or am I missing something ?
    – Puck
    Commented Jan 5, 2022 at 16:28
  • @Puck A1 and A2 share a secret that was not transmitted over the connection. If that shared secret is used as a cryptographic key, D can see the messages, but can neither decrypt them nor alter them in an undetectable way.
    – Bob Brown
    Commented Jan 6, 2022 at 14:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .