1

I'll preface this by saying I know approximately 0 about cyber-sec

I've made a server that will allow smart phones to act as a remote control for my house (eg turn lights on/off and unlock doors). Obviously the security of this server is very important to me. I would also like the latency on the app to be as low as possible so I designed the system to minimize the number of distinct calls to the server. If any of you could point out any vulnerabilities and/or unnecessary steps I'd appreciate it:

A message to the server takes the form of a get request to

/[username]/[command]/[random noise]/[signature]

I am using Sha256 as a hash function. the signature is calculated with

Sha256( Sha256( [username]+[password]+[command]+[random noise] ) + [previous successful signature] )

+ in this context means concatenation

If at any time you loose track of the previous successful signature you can request it. That is, the previous successful signature is public knowledge (and obviously that signature won't work twice in a row).

So far as I can surmise, I am not vulnerable to a replay attack (as the prev sig contributes to the next sig) nor a length extension attack (as appending to the message won't help and even if it did you could only append to the inner Sha256 instead of actual data).

Am I missing anything? Is my system secure?

SilverlightFox
  • 33,408
  • 6
  • 67
  • 178
IIAOPSW
  • 11
  • 1
  • I would worry about whether or not `username , password , command` can all be recovered from [username]+[password]+[command]+[random noise]. –  Jan 26 '15 at 07:04
  • Isn't that the point of hashing it? Or am I misunderstanding / misusing sha256? – IIAOPSW Jan 26 '15 at 07:07
  • 1
    If `username,password,command` can't necessarily be recovered from [username]+[password]+[command]+[random noise] then you may be misusing concatenation. –  Jan 26 '15 at 07:12
  • But its hashed after concatenation. How do you get username,password,command out of sha256("usernamepasswordcommand"). Isn't sha256 supposed to garble that effectively irreversibly? – IIAOPSW Jan 26 '15 at 07:20
  • Well, I [try guesses, since sha256 is fast](http://security.stackexchange.com/a/31846/49075). However, that's a separate issue from what I was bringing up (although probably more important). Does your system somehow rule out the case of `username0,password0,command0,random0noise` and `username1,password1,command1,random1noise` such that [username0]+[password0]+[command0]+[random0noise] = [username1]+[password1]+[command1]+[random1noise] but `[username0,password0,command0] != [username1,password1,command1]`? –  Jan 26 '15 at 07:30
  • fair point. There is no explicit check for that. I suppose if the user/pword combos "asdf"/"ghi" and "asd"/"fghi" existed at the same time, they could use each others permissions. Is there a recommended fix? Obviously comparing all pairs of users grows like O(n^2) which is undesirable. – IIAOPSW Jan 26 '15 at 07:41
  • https://en.wikipedia.org/wiki/Prefix_code –  Jan 26 '15 at 07:47
  • Oh yes it looks like you were talking about delimiters. – munchkin Jan 26 '15 at 07:55
  • What he is not saying is if your password on the REST based url is compromised through some form of decryption, then you have a big problem, which is why after the initial login, the only tokens that gets used are ones the server provides to say you have been authenticated. Edited . that is not what he is saying, but that is what i am saying. – munchkin Jan 26 '15 at 07:13

1 Answers1

2

A few things:

First, there is already a scheme to turn an unkeyed hash into a keyed hash. It's called HMAC; if you have a four step process (client says "send me a nonce," server sends client a nonce, client computes HMAC on the nonce with password as key and sends it back to the server, server verifies HMAC), that should work (the properties of a MAC require that an attacker without the password can't feasibly create any forged data-MAC pairs, even if he can get the real user to create as many data-MAC pairs as he wants. If the server does not repeat nonces (e.g. if it uses a counter), this should work; you don't need to worry about a random nonce, because HMAC doesn't require it.

Better, especially if you need to send any information afterwards, would be to use a standardized protocol like TLS-SRP. Unlike normal TLS, TLS-SRP doesn't require a certificate; you use a password instead.

No matter what, you should not be designing your own scheme. Designing your own security protocol is something that has a tendency to go badly wrong. Security is hard; minor mistakes can easily totally destroy the security of a scheme. Use a standardized protocol. TLS-SRP might work well; a regular TLS protocol would also work, but it'd be a bit finickier because you need a certificate. Other standardized authentication schemes can work too. But do not just throw data in a hash and assume it'll be secure.

cpast
  • 7,223
  • 1
  • 29
  • 35
  • Interesting. I didn't know about TLS-SRP, and one of my hats it web developer. There's a good reason though. From what I can tell there's no support for it in any major browsers. Firefox is still on a slow path to supporting it for instance: https://bugzilla.mozilla.org/show_bug.cgi?id=405155 I agree with not rolling your own secure authentication scheme. It seems like the best option is HMAC if you don't go the obvious route of TLS. – Steve Sether Jan 26 '15 at 18:51
  • One question. Is HMAC vulnerable to replay attacks? I've always used TLS, and haven't done much research on HMAC. – Steve Sether Jan 26 '15 at 19:01
  • @SteveSether My thought was if you were making a native app, you could use OpenSSL (which does seem to have support). If whatever you're using doesn't properly support SRP (like if you're doing a web app), you should definitely use something it does support instead of building your own SRP implementation (and one great thing about HMAC is it's easy to find implementations) – cpast Jan 26 '15 at 22:43
  • I'd be really leery of building an authentication on a poorly supported standard. Scope normally expands, and if you need to support the web, now you have two standards to support. Also it looks like HMAC is vulnerable to replay attacks, so you have to bake in a solution to prevent those. It's unfortunate we don't have widely supported standards for anything but TLS. TLS is a bad solution for embedded devices for instance because of the need for a client cert. TLS-SRP would be a great solution for such devices if it were better supported. – Steve Sether Jan 26 '15 at 23:25
  • @SteveSether HMAC with a server-supplied nonce is not vulnerable to replay attacks, though. It might be susceptible to MitM, but if you're not going to hit "open" unless you're physically present, a MitM doesn't help the attacker (you'd see him) – cpast Jan 26 '15 at 23:30
  • According to this reference, http://c2.com/cgi/wiki?HmacUserAuthentication Use of HMAC by itself doesn't prevent replay attacks. To prevent replay attacks, a unique message-identifier must be part of each message. So I'm a bit confused by your statement. I haven't studied HMAC, but the references I find say it's vulnerable to replay attacks. – Steve Sether Jan 27 '15 at 03:07
  • @SteveSether Hence, the nonce. HMAC by itself doesn't resist replay attacks because an attacker with an intercepted message and a MAC for the message can submit the intercepted message and MAC again. If the HMAC is required to be computed on a _new_ message that has not been seen before, you can't have a replay attack because captured HMACs will not be accepted again. HMAC isn't protecting against replay attacks; the fact that you never accept the same MACed token twice protects against replay attacks. – cpast Jan 27 '15 at 04:09
  • However, TLS may well end up being the best way to do this. – cpast Jan 27 '15 at 04:13
  • I was just confused about your statement about a server supplied nonce and what it really meant. But if you're invalidating a message after received, I believe you're right. TLS is preferable, but not always practical. It requires both certs, and regular maintenance. – Steve Sether Jan 27 '15 at 04:37