1

I have researched this topic exhaustively and am stuck -- was hoping to get some clarification from helpful folks.

Background: I have Bluetooth transponders attached to locks that are opened by payment in my app. A user pays a fixed fee, the lock opens, they grab their item, and the door closes and locks. I am trying to prevent spoofing attacks where non paying users are able to open these locks.

My current solution theoretically goes as follows: Each transponder is given a random 32 bit salt. Once the app Connects, an authentication request is sent to the transponder. The transponder then creates a random challenge string + its unique salt. The transponder then hash iterates the string 10,000 times (to protect against brute force) using SHA256.

While this is happening, the original challenge string+salt are also transmitted to the app which then sends it to a secure server via SSL where the shared secret hash key and transponder salt are also located. The string is hash iterated 10,000 times using Sha256 , sent back to the app, and back to the transponder which validates the server hash against its own calculated hash. If equal, the lock opens.

My questions are: is this secure? Am I overlooking some glaring security flaw whether it be brute force or other? Am I just completely wrong? Any help or recommendations would be much appreciated

user3682157
  • 111
  • 3
  • Why do you want to use a 32 bit key instead of a 128 bit key? – CodesInChaos Aug 03 '16 at 08:22
  • 1
    Yes, sounds like you're doing [Key Stretching](https://en.wikipedia.org/wiki/Key_stretching) when you'd be better off with a strong key to start with. 10,000 iterations only adds around 13 bits of entropy (45 bits total). You'd be better off with 128 bits unless the hardware is already fixed with 32? – SilverlightFox Aug 03 '16 at 17:04
  • So is the recommendation to use a different hash system such as PBKDF2 instead of sha 256 (in addition to the longer salt?) – user3682157 Aug 03 '16 at 21:29

2 Answers2

1

What you want is called a message authentication code. There are different ways to create one. What you describe is a trivial way to create a Hash-MAC, but has some security flaws. You might be OK with it, if your challenge string is fixed length and you append the "salt", which is actually the key, at the end. But there is a well defined way to generate a HMAC and I would suggest you to use it, because its security was studied. For most programming languages there are also good libraries to create a HMAC which reduces your work (and the things you could do wrong).

Josef
  • 5,903
  • 25
  • 33
1

Iterating a hash is a form of key stretching. This is usually achieved via proven algorithm such as PBKDF2 rather than simply iterating a cryptographic hashing function in your own way.

Key stretching in this manner is really only needed if you're attempting to take a user supplied password with possibly low entropy of which you need to increase artificially. If you can control the keys yourself and generate one with sufficiently high entropy, key stretching is not needed.

To get this clear you have:

App --authentication request--> Transponder

Transponder Authentication Key = 10,000 x sha-256(Challenge String + Transponder 32-bit salt)

Transponder --Challenge String + Transponder 32-bit salt--> App
App --Challenge string + Transponder 32-bit salt--> Server (via SSL)

Server Authentication Key = 10,000 x sha-256(Challenge String + Transponder 32-bit salt)

Server --Server Authentication Key--> App --Server Authentication Key--> Transponder

Transponder: Unlock if Server Authentication Key == Transponder Authentication Key

I'm hoping I've got that correct.

The only thing I'm not clear on is shared secret hash key - is this the challenge string or something else, as you haven't mentioned this term previously?

I am trying to prevent spoofing attacks where non paying users are able to open these locks.

What stops somebody from doing generating their own calculation of 10,000 x sha-256(Challenge String + Transponder 32-bit salt) and then sending this back to the transponder for it to open?

I am guessing that shared secret hash key is involved somewhere and what you're really doing on the transponder is

Transponder Authentication Key = 10,000 x sha-256(Challenge String + Transponder 32-bit salt + shared secret hash key)

If that assumption is correct, then it sounds like you need a Message Authentication Code rather than a plain hash with multiple rounds. For example, a HMAC.

If the challenge string is 128 bit and salt is 128 bit, this would give each authentication key 256 bits of entropy, and you should ensure that the shared secret hash key is at least 128 bit. See this answer.

From the transponder to app you would calculate

HMAC_SHA256("<shared secret hash key>", "Challenge String + Transponder 32-bit salt")

and Challenge String + Transponder 32-bit salt is then transmitted to app then server, the server then does the same calculation of HMAC and returns it to the app which forwards it back to the transponder for comparison.

SilverlightFox
  • 33,408
  • 6
  • 67
  • 178
  • Thank you Silverlight, very useful answer! My only question is why I would have the transponder transmit the shared hash key to the app? In my initial designs, the "secret hash key" would live only in the transponder and the server so there is no option to decompile the app and gain access to the key. In other words, for an HMAC, shouldn't the transponder transit (Challenge string + Salt) to the app, the app transmits to server, the server then calculates correct response using ("secret hash key" + Challenge String + Salt) – user3682157 Aug 07 '16 at 23:01
  • Sorry, a few semantic errors in my last paragraph. Just fixed, so I hope it makes sense now. – SilverlightFox Aug 08 '16 at 09:01