My web application is relying on container-managed security and I'm wondering if it's possible to use salted passwords at all. As far as I can tell it's easy enough to store digested passwords in a database by just configuring a JDBC or DataSource Realm, but there's no way to add a salt to those digest.
Any suggestions?
Edit: it seems I just need to think some more before asking questions ;-)
It's just a matter of choosing who's doing the digest calculation (client or server) and configure Tomcat accordingly.
If you're creating and storing the digests you can create and store the salts at the same time.
Your auth table would contain
....
pwdDigest varchar(64), -- or int256 if you have one
hashSalt int64,
....
Then depending on the auth protocol you're using you either send the hashSalt to the client when you get the username for client side encryption or use it to hash the password if you receive it in clear.
I'm not familiar with the database access technologies you're talking about, so I apologise if I've missed the point and oversimplified the answer.
Tomcat 5.5 and 6.0 don't support salted passwords in JDBCRealms and DataSourceRealms. It's a known bug, and the suggested patch seems to work fine, but it wasn't accepted yet.
If you don't want to apply the patch you can at least use it as an implementation example:
Bug 45871 - Support for salted and digested patches in DataSourceRealm
Passord-based encryption in JCE uses salt as per PKCS#5. See http://java.sun.com/j2se/1.4.2/docs/guide/security/jce/JCERefGuide.html#PBEEx for an example.
Related
I have just pressed 'forgot password' on hosting24.com, only to have my password emailed to me in plain text (see image below). I contacted their technical support to question this and they have told me:
We are using Salt encryption on our website, passwords are not stored
in plain text. Please let us know if you have any concerns regarding
the security of your data.
The way I understand it, is that once a password is 'salted' it cannot be reversed back to plain text. I am also very concerned, considering their partner company 000webhosting was victim of a massive hacking incident recently, which exposed that their security was sub-par.
Thanks.
EDIT:
After a few heated emails I finally got this response:
Our passwords are encrypted with a secure encryption method in the
database. Although we do have a decryption method in place (that is
used to prevent fraud), all this is going to change as we are
re-designing the project and updating the code to adhere to new age
standards. We are sorry to have let you down on this one.
Please contact us with any additional questions. Happy holidays!
'New age'. Amazing.
EDIT:
I sent the website this link to prove a point, so I anticipate a load of down votes from their tech support.
Salted hashed passwords are not directly reversible—that's the point of hashing. However one can always try to recover them through brute force, trying all possible/likely passwords to see if the hash matches.
How expensive that is to do depends on the strength of the hash used, but you would never build a system that stores and decrypts passwords that way. If they said they were storing only salted hashes, and still were able to send you the password you originally set yourself, they're clearly lying.
They don't mention hashing though:
We are using Salt encryption on our website, passwords are not stored in plain text.
“Salt encryption” isn't a thing, but let's be as generous here as we can.
It is possible they mean they're using reversible encryption with some randomised element (variable IV, or extra data in the encrypted message) which would ensure two passwords don't get matching encrypted versions (ie the same purpose as the ‘salt’ in a hashing operation).
It's also conceivable that there could be some valid reason why they need reversible passwords, for example if they need to use the passwords to authenticate to another separate system. It's possible to build reasonable systems with reversible passwords, but compared to Good Old Bcrypt it's a whole lot more effort to manage this way (eg keys on the application server; wide-ranging internal policies to manage that; HSMs; and watertight code auditing).
Let's say we accept that this is what they've done and they've implemented it solidly (which is highly doubtful—much more likely they've got plaintext passwords or a hacked-up and vulnerable AES). Even then, they've then blown it by sending you the reversed password in a mail over the unencrypted public SMTP infrastructure.
There are things you can do to mitigate the untrustworthiness of the mail channel, such as sending a single-use token or temporary password that requires a new password to be set afterwards. But there is never a good reason to send an existing password, that will continue to work on the target site and which you might have used to secure other services. User-set passwords should never touch SMTP.
No, they can't without astronomical computing power. I'd bet large sums of money that they have a second database of plaintext passwords.
In my website registration, for security reason, I hash password in client side and send the hashed version to server in registration request. But on the server-side, again for security reasons, I want to make sure that the entered password is longer than a specific length.
Is this a way for getting the length of a string from it's SHA1? If no, what other solution do you suggest for my situation to handle both mentioned security issues.
Thanks in advance
There is now way to do this. I you really want to hash it client side you should do the length checking client side before you hash it. Here are some tips on that.
A better way to do it though, is to just do the registration using HTTPS. That way the password is protected.
Problem with doing hashing and such by your self is that is could be done wrong. SHA-1 is for example deprecated. PS. Remember to use salt if you hash.
A con of https is off course that is opens up for possible man in the middle attack. If it really high security you could do both. This is most probably very overkill.
Don't do that.
Hashing a password on the client and compare the hash to the stored one on the server. is equivalent to storing plain text passwords.
An attacker has no need to know the actual password, it's like the hash has become the password.
This question has been answered before but the key difference may be that I want to be able to decrypt the password later on and that this is for a deployed application where someone could get a handle on the code assemblies (as opposed to a website behind a firewall)
Basically, I want my application, when deployed, to accept a user password. I want to store that user password somewhere (encrypted) and then decrypt it later for use in an automation routine.
I'll make a few assumptions to simplify things. You can assume that the password in memory is secure (while it is in memory) and that a strong hasing algorithm (feel free to name the best options) is sufficient. Even so, what would prevent someone from reflecting my code and finding the hash key or technique i'm using to decrypt the password (would i even store the hashkey in the code?). I could obfuscate but my understanding is that it is still possible to read. Also, note that one way encryption is not sufficient here. I need to decrypt and use the password later on. Any ideas?
To directly answer the question, you're looking for asymmetric encryption (not hashing which is a one-way process) if you want to encrypt then decrypt your data. The OWASP Top 10 on Insecure Cryptographic Storage is a good jumping off point to learn more about this.
Now to indirectly answer your question, don't do this! Passwords should be stored with a strong cryptographic hash function including a random salt (you'll see this mentioned in the OWASP link as well). If you're trying to return password ciphertext to plain text text then authenticate to other services whilst impersonating someone else, you're missing the root cause of your problem. You've not provided much info on this but it seems the question you should be asking is how you (securely) go about identity impersonation and authentication to a downstream service.
If you were to hash a user's password prior to sending it across the line and leaving it in plain-text in memory, would this improve the security of the application?
I would assume this mitigates a small fraction of vulnerabilities by protecting the data stored in the clients memory. But really if we're worried about someone reading the client's memory there are probably bigger problems that we can't address.
There's something that doesn't feel right about hashing on the client's end.
Is password hashing on the client end a common practice? Are there any other advantages or disadvantages to doing it?
EDIT:
Given the communication channel is secure (SSL). Under what conditions would it be acceptable and worthwhile to use such an approach. I'm asking this because it was suggested by a "security professional" that I use such a scheme during some application functions.
No.
When the client sends something, whether it is P or H(P) or H(H(P)) anyone who intercepts this can simply resend the exact same thing, thus making any function like this equivalent to using the password directly.
That's why you should use a nonce; The server can give out some random garbage k and the client will calculate H(P,k) and send it to the server. HMAC is a popular implementation of this method.
Provided the server never accepts the same nonce twice, this is secure against a replay attack.
Sending a hashed password won't improve security on your site, as others have pointed out (since you accept a hashed password, all the bad guy needs to know is the hashed version). It's also not really secure, since the bad guy can presumably load your login page and examine the Javascript or Java deployed.
What it does do is prevents somebody watching the packets from being able to pull out a password, and that is moderately useful. Many people use the same password on multiple sites (I do it for all but the higher security sites), and therefore if you can get one password from them you can log into other accounts on other sites.
It also prevents the real password from being stored, even temporarily, on your site, and that may provide a little extra security if your site is compromised.
So, while I'd consider user-side hashing to be potentially a good things, it isn't worth going to much extra trouble.
And, as others have told you, don't roll your own security. There's far too many things that can go wrong. You won't notice them nearly as fast as a practiced bad guy will.
The hash is identical to the password from a security POV in the scenario you describe: if I intercept the hash, I don't need to know the password, I can just send the server the hash I intercepted.
Authentication protocols go to some length to avoid this problem; security is hard, and you are best off selecting and implementing a well-understood protocol rather than rolling your own.
If your traffic is going over SSL, you're safe from interception and hashing gives you little extra benefit.
Yes, you should.
IEEE had a data breach in which 100K emails and passwords were exposed from a weblog.
http://ieeelog.com/
Obviously, IEEE should not have exposed their weblog! But if they had hashed the passwords at the client side, this wouldn't have been nearly as bad.
As the first answer states, you should use a nonce. If you use a long enough nonce (e.g. 128 bits), you don't really need to worry about reuse, as the server will never ask for the same nonce twice (assuming correctly seeded CRNG, etc.).
No, hashing at the client does not protect the password 'completely'. When one opts to hash the password at the client, then the digest submitted to the server, essentially becomes the password. This is not a problem in itself if SSL is deployed.
However, this scheme ends up creating more problems than it solves. If the server were to compare the hash submitted by the client with a stored hash in the database without performing any further cryptographic operations (especially hashing the input data), then the password is stored in clear text for all practical purposes. Any person with access to the stored hash can re-submit it to the server and gain access to accounts.
In simple terms, if the submitted hash (which is the same as the submitted hash) were to leak via any other vulnerability within the application (via SQL injection, for instance) then the application has a vulnerability where in it protects the passwords inadequately.
If the underlying vulnerability must be fixed, then it is necessary to treat the submitted hash as a password in clear text, which should then be hashed (with a salt preferably) before comparison with a stored hash.
I think it makes sense in one circumstance; you don't want to even know the client's plaintext password. If you hash at the client side, then salt and iteratively hash that hash the same way you would a plaintext pw. Other than that, its kinda silly.
Just make sure that you are sending your password through a secure channel (SSL). If the client can have an application private memory read, then most likely they have bigger problems, like for example a keylogger.
You'd be much better off if you used the Secure Remote Password protocol (SRP). It was designed for this.
I can give you different kind of approach
If you have not SSL you can hash password on client side and again it hashed on server side using another hashing method and store them on database
and when user login with password do the same process and match double hashed password with stored hashes
Yes it makes sense to hash the password on the client side even if you use SSL but still you must also hash it again on the server side.
This makes sense especially in case of a mobile app. If you hash on the client side even with a "constant salt"/domain string it will be much better than sending a password in plaintext even if you use SSL. If you send plaintext passwords to the server then in case someone hacks your server he will receive password in plaintext. So adding additional pre hashing on client side protects the users and their password which they probably use also in other places.
You will probably find many posts saying that client side hashing is not needed but they usually are related to a web apps and do not consider mobile app case. In case of a web app if someone hacks the server he can replace the website and remove the client side hashing anyway so in such case there is not that big advantage. But for mobile apps an attacker cannot replace code of the mobile app so hashing on the client side has a lot of sense in such case.
You can check this link for a possible solution with hashing on both client and server side: https://medium.com/#harwoeck/password-and-credential-management-in-2018-56f43669d588
So yes, hash on both client and server side.
Hashing on the client side opens up another huge hole: you may expose the hashing algorithm. You don't say whether this is web-based (client=JavaScript) or thick-client, but you're giving them more information. Given the channel is secure, you don't have to worry about the clear text password being sniffed.
Besides, if your hashing algorithm requires a salt, you would be exposing your salt, which means if they ever got access to the database, they would be able to decrypt every password.
Situation 1 - Connecting the server to the database:
Its always said that passwords should not be stored in plain text, however to connect to the mysql database requires the password, in plain text it seems... I'm guessing the best solution to this is to store it in an encrypted form, decrypt it in my app as needed and then erase it from memory (SecureZeroMemory in windows I guess so the compiler cant optimise it out).
Situation 2 - Users logging into the server from a remote computer:
As for users passwords my plan is to never actually store the original password at all.
Instead I will store a randomly generated "salt", for each user, prefix there password with it then hash it, which seems to be a relatively common way. However I don't have an SSL connection available at this point, so I'm guessing the plain text passwords could be intercepted, what's a good solution to this?
What are good algorithms (links to C/C++ implementations would be handy as well if you have them) for doing this, a look on the net comes up with 100's of them?
EDIT:
If I got SSL, would the following be secure (assuming a strong hash algorithm is used), or should a different method be used?
Client requests salt for a user name
Client prefixes password with salt, then hashes it before sending the hash to the server
Server compares hash recieved to the one on the server for that user name
Connecting the server to the database
Just storing the database password in the server - encrypted or not - is a bad idea. It is obvious storing it in plain text, of course. And if you just store it encrypted, the server still needs the key to decode it. It is usually not very hard to find the key in the server code. The best solution is to let the user starting the server enter the password and store it nowhere. Alternatively - and probably even better - you can store all sensitive information - for example database users, passwords, and so on - encrypted and let the user starting the server enter a master key to decrypt this information.
Connecting a user to the server
This is really a hard problem and easy to mess up. A quote from this great article article on the topic I absolutely recommend reading.
No, really. Use someone else’s password system. Don’t build your own.
A good solution might be using the Secure Remote Password Protocol.
You are correct that if you're not using SSL then the passwords can be intercepted.
It is common practice to never decrypt a user's password, so keep it stored hashed with a salt and when the user types in their password you will add the salt and hash it, comparing it with the stored, hashed password. This will allow you to never have the decrypted version of the password every.
You really should look into securing the connection so that the password is secure when the user types it in.
Update to answer edited question:
If you have the communication secured using SSL you can still use any number of extra measures of security you like including hashing the password. As added security it is a good idea to remember that the password you store should be stored hashed with a salt. That salt should be kept safe and never be accessible anywhere except by your application. This way when the user submits the password you just add the salt and hash and you compare that version with the stored version.
Situation 1 - Connecting the server to the database
There isn't an easy answer here. In order to connect, the server needs the password (or symmetric key, or private key or whatever). It must get it either from the disk or some external means (like an administrator typing it at startup). Adding some indirection, such as encrypting all the sensitive stuff under a master password, can add some convenience but otherwise doesn't change the situation.
Typically, it is fine to put the password or key in a file on a server. If you do this, make sure to set the permissions on the file so that only the users that need it have access to it. This is an excellent reason to have different processes on your system run as different users, and to set up separate roles/accounts and passwords for each.
Situation 2 - Users logging into the server from a remote computer
You are headed in the right direction here, I think. What it sounds like you're asking for is a secure authentication protocol. You want one that provides mutual authentication and prevents a man-in-the-middle attack by failing if such an attack is attempted. There are many to choose from of course.
It is also worth mulling whether your authentication should operate based on "something you know" (passwords) or "something you have" (public/private keys). Assuming based on your question that what we're looking for is passwords, two that I like are SRP and Kerberos.
SRP was mentioned earlier, and that doesn't get nearly the attention it deserves. SRP has the advantage that it doesn't require the server to know the password, or key, or anything that an attacker could use to gain access. If you broke into a correctly configured server using SRP and stole all the data, you'd still need to do something like a dictionary attack on each key individually before you had anything you could use to impersonate a user.
I also like Kerberos because it is supported by tons of software (I know Postgres supports it, I've only found mentions of mysql not supporting any good authentication technology) and has a system of 'tickets' that provides a single sign on capability. Kerberos needs some other technology to help strengthen its initial authentication exchange and SRP would be great for that but I'm not sure they've done that yet. Something about it making the KDC (key server) stateful I think.
Kerberos' weakness is that you have to be more wary of the server storing the keys. While it doesn't store the passwords in plaintext, it does store the keys, which are essentially hashed versions of the passwords. And while the client doesn't exactly send either the password or the key straight over when authenticating (this is a Real auth protocol after all), it does use the hashed password as the key, and so anyone else who knows the algorithm and knows the key could do the same. We say that the server stores a "password equivalent". As a result, all the manuals tell administrators to put the kerberos services on their own separate, locked-down boxes to minimize the chance of compromising their contents.
The nice thing is, once you settle on a strong authentication exchange, other good things typically fall out of it for free. You end up with both parties sharing a mutual 'secret' that can be used once for the duration of the session, never sent over the wire, and can't be known by a third party. Want encryption? There's the key, all ready to go. This is exactly how SRP-secured SSL is defined in RFC 5054.
Not sure if this is what you are asking for.
But a simple PHP example using the built in sha1 function:
// Check the hashed password from the database
if (sha1($salt.$password) == $providedPassword)
{
// User is authenticated
return TRUE;
}
else
{
// User is not authenticated
return FALSE;
}
One thing you could do is also hash the password with javascript before it is sent over the wire. The question is how is the salt string shared between client and server? One possibility is to use a session variable. And then use the session variable to unhash the password afterwards on the server. This would mean that the man in the middle would need to know one other piece of info to make sense of the password. Not as secure as SSL, but perhaps an extra layer of defense against casual network sniffers.
I could also imagine a hashing scheme linked to some sort of captcha system used to salt the password on the local client before sending over the wire. The client would be providing the text for the salt string by completing the captcha. You could look it up on your end.
The main concern is the man in the middle not understanding the plain text password.
SSL should be used, but the above techniques might be useful where SSL is not possible.
Newer MySQL uses hashed password over the wire, so you don't have to worry about man-in-the-middle.
If you worry about the password stored in your configuration file, you can encrypt the configuration file with a password. However, the problem is that you have to enter a password to start your application.
I wrote a similar application over 15 years ago. Back then, PGP was my choice. I am not even sure it's still around.