Encrypt password from client side using AES? - encryption

I want to encrypt the password sent from client side. I found crypto-js which provides AES implementation. My question is that if i use a "passphrase" for encryption, will anybody who can view the source of the page can also see my "passphrase" too ? If i have the wrong concept please help me clear it.

No, you cannot just read the password if it is not stored in JavaScript.
However, in almost any case where the JavaScript code can be read, the JavaScript code can also be changed. And if you cannot trust the code, then all bets are off - the password may be send to or retrieved from anywhere.
Take for instance an internet cafe. You connect to "coffeeplace.com" but you're actually logging on to a hoax service. In that case any unprotected connection can be altered. If the hoax service has obtained a rogue CA certificate then this is even true for HTTPS connections.
If you want to protect a password you should send it over a HTTPS connection. If you want application level security on top of the HTTPS transport security then you could encrypt the password using a public key; the server can then later decrypt it with a private key.
Application level security is useful if you want to store the password (hash) securily on your servers for instance. You could then later process the encrypted password using a service in the back-end.

To answer your actual question: Yes, everyone will see the passphrase.
But really, do some research on:
password hashing: Do you really need to know the plain text of user's passwords?
why using javascript for crypto is a really bad idea in almost all use cases.
Information security in it's whole
or please leave information security to people who know their turf. You are quite probable to introduce new problems, because crypto is hard, even with all the best intentions.

Related

What happens between the time a user sends a password and when the server receives it?

I'm trying to understand something. When I implement PBKDF2 in a server and client, it is my understanding (could be way wrong, sorry), that the server keeps the encrypted/hashed password in the database, and the user sends his or her password over the net and then it is checked by the server for validity.
What Im curious about is, exactly how do I prevent the users submission over the net to be seen and the users password exposed? do I Just depend on the networking library or SSL to protect this information?
How do i make sure the the password that's being sent over the net is in a way that cannot be exposed easily, but can still be read by the server to check against the hash?
Would it be wise to perform an SHA2 hash on the password client side, and then send that to the server and then check the sha2 has against the PBKDF2 hash? The server will never really even know the users password, the only possible recovery option is to reset it. Is this type of system acceptable?
What kinds of these things are done normally by the professionals?
When I implement PBKDF2 in a server and client, it is my understanding (could be way wrong, sorry), that the server keeps the encrypted/hashed password in the database, and the user sends his or her password over the net and then it is checked by the server for validity.
This is basically correct. When setting up an account the user sends user and pass to the server. The server stores user and PBKDF2(pass) and then discards pass. When logging in the server looks up against the user column and compares PBKDF2(pass_as_submitted) to the value stored when the account was set up. If they match, the user is authenticated.
Do I just depend on the networking library or SSL to protect this information?
In the sort of situation you're talking about, yes.
Would it be wise to perform an SHA2 hash on the password client side, and then send that to the server and then check the sha2 has against the PBKDF2 hash?
No. The problem here is you're just changing the thing you're keeping from the user's password to a hash of the user's password. It's still known to an attacker who can read the database.
(There are reasons this is marginally better than knowing the password, most particularly in case of password reuse. However, these do not justify such an approach.)
It's worth pointing out as well that SHA2(password) will not match PBKDF2(password).
What kinds of these things are done normally by the professionals?
First, use TLS (aka SSL). Having a good, encrypted connection between client and server is first priority. For a website, you should use TLS on every page, not just when sending the password. At the very least it must be used on the login page and on the request that receives username and password information.
Your TLS connection should be set up properly: it should use HSTS if appropriate (and it's a website). It should avoid outdated algorithms (only support TLS 1.1+ if possible). It should use appropriate cipher modes.
Beyond that, it depends on your use case. Perhaps it's worth implementing two factor authentication - be it using TOTP or SMS codes or similar. Perhaps you should be looking at logins without passwords, for example using client-side TLS certificates or OAuth2 tokens. Maybe you should use an existing authentication library like Kerberos. Maybe you need to look at password policies to ensure users are setting good passwords or pass phrases.
These questions are complex and depend on your use case. Thinking about them is the big first step most people don't take. Using PBKDF2 is a great start but there's no universal answer. If possible, get an expert to do your security analysis. If not, open source plus some promo can often get people to look at it. Worst case scenario, read up on security, check out the OWASP Top 10 and think about every part of the system. Where possible use existing libraries made by experts. If you have to roll your own, you're probably doing it wrong.

Can https fallback to http and security level of https

I am considering installing SSL/TLS for my domain. There are two questions that have been bothering me:
Is there any scenario where a https connection can fallback to http? So, for e.g. if my ajax looks something like this
$.post("https://foo.com", function(){
});
Is there any chance this could change to
$.post("http://foo.com", function(){
});
and even if it does would my domain be still accesible at http://foo.com ?
Next I have read extensively about using SSL/TLS and from what I have read it seems to be fairly accurate to assume that if I have this enabled and even if I send the user credentials in plain text, it's still secure (There would be encryption with salt and everything on the server of course). To what extent is this true and would creating a hash on the client and then sending it over https be any more secure?
Update: If sending plaintext over SSL is secure enough, then what really is the point of using things like cnonce ? Isn't it just unnecessary overhead on the client?
No, HTTPS never falls back to HTTP automatically. It would take deliberate action by the user. If you're just going to a web page by putting its URL into the address bar, this is easy; for form submission it's harder.
Yes, sending plain text over SSL is fine. In fact, sending a hashed password doesn't really increase security much at all -- if someone manages to sniff the connection and gets the hashed password, that's all they need to be able to login to the site. It has one small advantage: if the user uses the same password at multiple sites, learning the hashed password for one site doesn't help them get into another site that uses a different (or no) hash. And it's not likely to be feasible to send salted hashes, since the client doesn't know the salt.
A cnonce adds an extra level of protection. If, somehow, someone manages to crack the SSL encryption, the cnonce prevents them from getting a usable password from it. This basically addresses the point I made above about why sending a hashed password doesn't help: what you need is something that changes from session to session, and a cnonce provides this.
See https://security.stackexchange.com/questions/3001/what-is-the-use-of-a-client-nonce

asp.net membership password security

I noticed when looking at the templates for mvc internet applications the password is sent from the client to the server in plaintext, although I believe it is probably encrypted/hashed+salted when stored in the database.
Is the best thing to increase security here to enable SSL/HTTPS only or would it also be best to hash the password on the client side so it couldnt be intercepted en-route to the server or is this overkill?
Is there anything in the asp.net framework or 3rd party tools that would help with such a client side encryption/hashing?
The correct solution here is to use SSL encrypted page (and SSL post back - meaning post to the same ssl page, or to other ssl page)
If you try to encrypt it or hash it before send it with javascript you just make your code more complicate and not add so much to the security of it.
To say some more thinks, let say that some one in the middle get the post back values, then the hash of the password is usual 48 to 128 bit, less than the SSL security that have a key f 2048 bits. So no special gain if you hash the password before send it.
It came to my mind one more issue : if you make the hash of the password on client side then you expose your key, and if some one get your key, then can create from the hash, passwords that give the same hash. So do not make the hash/salt of your password on client because you have also a security issue.

Security purpose

How to Encrypt Client side login before sending to server ?
You should use HTTPS.
Building security by yourself is hard, and you are very likely to get it wrong.
You should stick with the systems that the experts use.
On the server, remember to hash and salt the passwords, preferably using bcrypt.
There's one very simple solution. SSL. Ensure that all your login activities are served via https:// URLs.
The way that you do this, at least the "setting the server up" part vary depending on what web server you're using. You'd be better off asking a question of that nature on http://www.serverfault.com/
You can only use https - any client side encryption would be viewable on the client and therefore useless. There is SO question on this: password encryption at client side
You should really use HTTPS, but if you can't use HTTPS then the alternative is to create a hash.
Server generates a random 'salt' for the session
JavaScript on client-side creates a cryptographically secure hash of the user's password and the salt.
Hash is sent to the server, you can then retrieve the password from the database, create a hash using the salt for the session and the password from the DB and check if it is the same as the one sent from the client. - If it is then the password is a match.
An example of using JavaScript to protect passwords: http://pajhome.org.uk/crypt/md5/auth.html

Is it possible to hash a password and authenticate a user client-side?

I often make small websites and use the built in ASP.NET membership functionality in a SQL Server database, using the default "hashing" password storage method.
I'm wondering if there's a way to authenticate a user by hashing his password on the client and not sending it in clear text over the wire without using SSL.
I realize that this would only be applicable for users with Javascript enabled.
Or... possibly, this would be a great built-in capability for Silverlight (is this in the Silverlight roadmap?)
EDIT:
I'm also looking for "degrees of security." Meaning, if there is a method that has some advantages over simply sending plaintext password, I'd like to know what they are and why.
I know there are lots of people who do small sites with logins (such as a family website or volunteering to make a site for a local cooking club) and don't see the need for purchasing SSL certificates.
This is possible. This is actually what Kerberos authentication does, only with a little bit of added spice. To ensure that your authentication mechanism is secure, you need the following:
A common hashing algorithm on both the client and server.
A one-time salt value generated on the server and shared with the client.
The original password stored in a database.
To securely authenticate a user via hash code, so you avoid sending the actual password across the wire, first generate a random, single-use salt value on the server. Send this salt value to the client, and generate a hash code from the salted version of the password the user has input. Send the resulting hash code to the server, and compare it with a hash code generated from the salted version of the stored password. If the comparison fails, discard the salt, regenerate a new salt value, and repeat the process.
The reason for the single-use salt is to prevent anyone listening to the conversation from capturing the hash code of the users password, which, when you use hash code comparison, is just as good as having the password itself.
Note that you need to keep the original password around, you can't hash it once on the server and save the hash in the database. If you need to ensure that the passwords stored in your database are also secure, then you will need to encrypt them before storing them. I believe that ASP.NET membership providers do allow you to store passwords encrypted, however, if you really wish to have a secure authentication mechanism that is difficult for a hacker to crack, then I would recommend handling password storage and retrieval entirely on your own.
Finally, I should note, that such a complex password transfer mechanism should be largely unnecessary if you use SSL to encrypt your connection during authentication.
References (for those who have never heard of Kerberos or SRP):
http://en.wikipedia.org/wiki/Kerberos_(protocol)
http://en.wikipedia.org/wiki/Secure_remote_password_protocol
This is a bad idea, security wise. If you send a non-ssl form that contains the hashed password, then anyone capturing traffic has all they need to login. Your javascript has to result in something that indicates success (a redirect, token passed to the server, etc). Whatever it is, the listener now can recreate that without proper authentication.
SSL was built for a reason, by people who tried a lot of other web authentication schemes. It is far safer and cheaper to get a cert than to try write your own safe authentication scheme that works without encryption.
Added for clarity:
Client side hashing alone is not safe. Say I have a form with the following inputs
<form action="signin.whatever" method="post">
<input type="text" id="txtUser">
<input type="text" id="txtPass">
<input type="hidden" id="hiddenHash">
<input type="submit" onclick="hashAndSubmit()">
</form>
where hashAndSubmit() hashes the password and puts it in hiddenHash, and blanks out the password field. If I sniff your submission and see the following fields:
txtUser:joeuser
txtPass:
hiddenHash:xxx345yz // hash result
that's all I need as an attacker. I build a form with your user and hash value and I'm all set. The password is not necessary for a replay attack.
To get around this, you have to look at one-time salt values, or other schemes. All of which introduce more cost(don't forget developer time) and risk than SSL. Before you do something like this, ask one question...
Do I trust myself more than years and years of public testing of the SSL encryption?
You could do this, but it would be just as insecure. The problem is that someone could capture the hash and replay it (just as they could the original password). I suppose you're providing some protection against the exposure of the actual password (in case they use it on other systems), but your system will be no more secure.
You can implement your hashing algorithm client side (in javascript) and send only the user name and hash result over the wire. Note that in order for this to be secure the hash must be salted with a string provided by the server, and the string must be unique for every request. The sever still needs to check whether the hash is correct or not and authenticate the session.
At least you have to use a salt for generating the hash. Otherwise the hash value is as "valuable" as the plain password when intercepted - at least on your site.
You can send as post fields the username/realm/password hash following the HTTP Digest protocol. AFAIK there is no built-in client component nor server side component to generate/validate this so you have to do everything manually. It also requires your storage to store a specific hash format, see Storing password in tables and Digest authentication
The advantage is that you're following a well analyzed and understood authentication protocol. Don't roll your own.

Resources