3

i am trying to secure a connection between a Mobile Device (Client) using a webApp and a Home Device (Server) in a potentially unsafe Wifi Network.

The communication is asynchronous and i am trying to prevent "replay attacks".

I was thinking about Challenge Response, but the overhead of "ask for challenge, receive challenge, send message with solved challenge" is a performance issue for us.

So i was thinking about using some sort of TAN Book approach like online baking does it:

Initially the Client would ask for a set of Challenges that it stores. The Server would store those Challenges and keep track of how many are already used.

If only n Challenges are left, the Server creates new Challenges and sends them with the next response to the Client. This way, the Client should almost always have enough Challenges without the overhead of Asking for them first before every request.

Example:

  • Client wants to log in and asks for challenges first, giving his username/userid.
  • Server creates n Challenges and stores them for the given userid, then sends them to the user.
  • Client sends challenge-id and hash(challenge, shared-secret).
  • Server compares stored challenge (identified by challenge-id) hashed with shared secret and if correct, returns success and deltes challenge since it was now used.

then it gets easier

  • Client wants to call API Endpoint X on Server, sends request with added Headers (challenge-id, hash(challenge, shared-secret))
  • Server checks challenge and uppon success deletes it, executes method x and returns response. In response it adds a new challenge in the header (i.e. challenge_id-xyz: 45egrgh3gw43gw43zrezh54egh44zg54b54esb...54sreh5j)

if the client is low on challenges

  • Client wants to call API Point X, sends Request with Challenge in Header
  • Server checks Challenge, upon success deletes it, realizes the client is low on challenges (due to low amount of stored challenges) and creates new ones. It sends Response for API Point X and adds new challenges in the headers.

Is there already a concept like this and if not, does this sound to much like "bake your own crypto" or does it sound legit? Or is there a better way to do this without to much http overhead?

Andresch Serj
  • 217
  • 1
  • 8
  • I don't think you are baking your own crypto, since it is only a matter of WHEN you are sending the challenges. A challenge might be only valid for a certain amount of time, which does not play well with your concept. You might take a look a the OCRA algorithm, which is rfc 6287. – cornelinux Feb 26 '15 at 22:40
  • I would let Challenges expire. The Server would keep track of the timestamps as well and use that information to decide weather or not to create/send more challenges. Also: If the client ends up not having any challenges left, it can always ask for new ones as well. – Andresch Serj Feb 27 '15 at 09:06
  • Of course the server can keep track of challenges and its expiry. You can take a look at [privacyidea](http://privacyidea.org). I provides challenges response but it only sends ONE challenge to the client at the moment. Not a bunch of... – cornelinux Mar 02 '15 at 13:56

1 Answers1

2

Well in answer to your question as to whether there's a better way to do this, I'm wondering if a slightly simpler solution which I've used previously might be up to the task.

Rather than generating a pre-defined list of challenges and transmitting them, have the client and server each add a predictable incremental value to the hash you pass in the header. Both the client and the server keep count of the number calls/responses for the session and can reject any received with duplicate (re-used) hashes. The incremental value can be as simple as a count, or could be some simple maths function performed on the count if you're feeling particularly paranoid.

It would look something like this:

  • Client wants to log in and sends a login request with userid & hash(some sensible combination of shared secret with userid or some such).
  • Server examines the hash and if correct, returns success and a session token.

Now for each call made:

  • Client calls API endpoint X on server, with added header hash(session-token, incremental value)
  • Server verifies the hash matches the session-token & the next incremental value expected for this session, if it does it sends the response from the endpoint also signed with hash(session-token, next incremental value).
  • The client verifies the response header contains a hash of the session token and the next incremental value it was expecting.

and repeat.

If any request/response arrives with a re-used hash in the header, the incremental value will be out of sequence and the client/server can reject it. Also there's no need to worry about generating, transmitting and maintaining a list of challenges for the session.

Downsides here involve problems caused making multiple calls and them getting out of sequence either due to network issues or the design / requirements of the application. Ways around this involve adding a central point to the client to marshal/queue all requests and responses for the session, or alternatively create a separate session for each thread or conversation within the client application. That's extra consideration during development maybe, but if your requirement to keep traffic to a minimum is important enough it might be worth the effort.

Comments and thoughts are very welcome.

GreatSeaSpider
  • 2,054
  • 16
  • 14
  • Thank you for the detailes answer. Problem is when you use asynchronous communication - then the count will not be that predictable :-/ – Andresch Serj Mar 23 '15 at 11:33
  • 1
    Thanks for the comment! Yes that is a problem, as I mentioned towards the end of my answer you could work around this in a few ways, depending on what exactly you are building. All the different answers involve some extra effort though. For a mobile client app I'd probably try to ensure all the calls are made through a marshaling component which could keep track of the calls & responses. – GreatSeaSpider Mar 23 '15 at 13:26
  • Well, the concepts (queue of requests/separate session) are not practical for my szenario (mobile remote controll) because of the performance issues it brings. :-/ Still a good Answer (+1) – Andresch Serj Mar 24 '15 at 09:00
  • 1
    No worries, if it doesn't suit your scenario then it doesn't suit. Thanks for the vote! – GreatSeaSpider Mar 24 '15 at 11:32