TL;DR
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
As everyone else has already stated, this cannot protect against MitM. This is the standard threat model used and nothing done in the browser can solve it assuming you're using the internet to receive your code. If, as you say you're going to use a USB drive to distribute the key and JavaScript (and presumably some HTML) then yes, you can bypass the MitM problem for the authentication sequence (we'll assume you can manage to safely distribute these USB sticks).
It is worth mentioning that beyond the problems of MitM for the authentication bit, there are several other problems with JavaScript. Just a quick for instance, say you used AJAX to load the pages. A MitM would be able to change what you get back and unless you're very careful you could very well fall victim to a cross-site scripting attack where the attacker can then capture your key data. Basically the problem with JavaScript is that it is very hard to "seal" the execution context. With most programs you write them and it's reasonably easy to say this is the program and nothing else can be added after the fact (don't call methods like eval
, don't load arbitrary libraries and as far as the language is concerned you're safe). I'm ignoring issues not stemming directly from language features, like buffer overflows, because the point I'm making is that JavaScript is so automated that you can very easily run code from an arbitrary outside source without meaning to, all with the support of the language.
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.
Final Conclusion
Just to clarify, I agree with what everyone else has said. I don't see the value in doing things this way. You would have to explain more why you have a problem with using standard https (TLS/SSL) to handle your problem. Every modern browser can handle it and it handles everything from what you want (authentication) to many other things that people generally want (like confidentiality). There seems to be some feeling that setting up https is complicated (which I don't agree with). However, it is most certainly easier then trying to write your own JavaScript version complete with USB distributed keys and the like.