I have a WebService which has several calls which are only available to members of the site. I want to build a pure html/jQuery mobile app which can call into this service make requests and download information.
My initial plan was to put the users' username and password in the auth header but I'm worried about exposing them to any traffic sniffers. I can obviously create a session key so after the initial authentication they call in with a token but this may be vulnerable to session stealing.
My current plan is:
Another thought was to encrypt the password as I send it. Is it possible/sensible to do public/private key encryption in JS based on the .NET RSACryptoServiceProvider implementation?
What is the best approach to handle authentication, ideally without purchasing an SSL certificate (the data itself is not particularly sensitive). ?
Apart from obvious reasons why SSL is highly recommended, and you should definitely use it if it's possible, you can consider rising your security by hashing your login and password.
Hashes work in a way that is very difficult to break - hashes of very similar strings are completely different, even if you only change one char. See that:
Login: "jacek", SHA1: "9749d1492af3d43f9c09e04c5c43f27bb909af51"
Login: "Jacek", SHA1: "46c676716f0e9aa86545c034d0e22a114d7cd488"
This shows that you need an EXACT password (or it's hash collisions, which are difficult to compute) to 'break' the hash, and a 'simmilar' one is completely useless.
Your implementation may go like that: When you create a user (f.e. registration moment), you compute hash of login and password. After that, in DB you will have:
Login | HashedLogin | HashedPassword
---------------------------------------------------------------------------------------------
jacek | 9749d1492af3d43f9c09e04c5c43f27bb909af51 | e4e088f4eaa96db85e11ba491a189f96f2e11793
(You may keep an unhashed login for debugging / maintanence purposes only.)
After that, before you conect to Web Service in your app, you do exactly the same, but in jQuery:
var _HashedLogin = Sha1_Hash($("#login").text());
var _HashedPassword = Sha1_Hash($("#password").text());
There are lots of third-party SHA1 libs, use any of them ;)
Then, when you send info to your webservice, send the hashed values only. Even if someone sniffs your ajax call, he will only get something like:
"UserInfo":
{
"login" : "9749d1492af3d43f9c09e04c5c43f27bb909af51",
"pass" : "e4e088f4eaa96db85e11ba491a189f96f2e11793"
}
This is useless for the thief, but you can easily compare those values with your precomputed hash in the database. You can run
select id from Users where HashedLogin = 'login_from_your_ajax_call' and HashedPassword = 'pass_from_your_ajax_call';
If you get any result of this query, your secured verification is completed and you have the Id of a user. If there are no results, the login or password is invalid.
SHA1 is quite secure for home and semi-pro reasons, to compute a hash that will collide your password, you may need up to 2^61
comparisons. It would take literally YEARS for a home computer to break that. This solution is still vulnerable to the man-in-the-middle attacks, but is a leap of security from sending plaintext authentication data.
Also, REMEMBER that even once the user is authenticated, unless you use SSL, ALL the other (client <-> Web Service)
connection is still insecure and easy to sniff.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With