While technically there are threat models where your method provides an advantage over straight http, I'd still suggest using https. See conclusion for more details.
Security Problems Related to MitM Attacks
Slight Redemption in Lieu of Reduced Threat Model
What I would like to add is that this does protect against eavesdropping (which is a bit more realistic attack then full MitM). You still won't be able to protect the information that goes back and forth, but at least they won't have access to
key. All I'm trying to say here is that there is a significant superset of MitM attacks that include packet capture but not necessarily control of the network stream. Say for instance I take a packet capture for some network diagnostic reason and then save this somewhere insecure. Your method does technically protect the keys from being stolen in such a case.
Clarification of How to Provide Any Sort of Useful Authentication
A further note, you didn't explicitly state it so I thought I'd clarify it. In order to prevent the eavesdropper from being able to use
answer to access anything other than what the original client is asking for you need the following process steps:
- Client makes request
- Server makes
challenge (as you stated)
- Server associates
challenge with whatever it was the client was asking for
That means that the
answer will only be valid for the original request (can't be reused). If you're going to use this as a general login scheme where you then provide a session cookie to the client you should know that even an eavesdropper (without MitM capabilities) would be able to impersonate the computer that's logged in until such time as the user either decide to log out or the session expires.
Answer to Question Relating to Key Size
As for how long your challenge/key should be. The chunk size of the SHA-2 hashes (of which SHA-256 is a member) is 512-bits. So if you made the challenge and key 512 random bits each (so 64 completely random ASCII characters) you would be fine.