Not storing passwords in plaintext is good in theory, but
in practice it’s not always possible.
In practice it is always possible. I know of no mail client that does not support either TLS or SSL connections; there has not been a need to support plaintext authentication for mail relay for some years now.
And if you tell me that “I have a user that will only use a particular piece of broken software”, the answer to that question is “plaintext passwords are no longer an acceptable security risk in today’s internet, sorry.”
You can’t use telnet for remote administration any more. You ought not to be using unencrypted POP to get your mail, or unencrypted SMTP to send your mail.
If you are using .NET, you may find the SecureString class to be helpful in storing passwords. SecureString keeps sensitive data encrypted in memory so that it cannot be easily stolen. SecureString plugs a specific security hole but does not guard against all threats while securing information in applications.
It’s really simple, Joe User puts his password in wrong 3 times and his password is locked, changed,
An attacker is likely to convert your account lockout setting into a denial-of-service attack, by locking out every account on the system. And a scheme like this is a massive burden on the helpdesk.
Why would you not list account lock-outs as a defense against brute force attacks?
It’s really simple, Joe User puts his password in wrong 3 times and his password is locked, changed, and he is sent an e-mail telling him to come set a new password or call customer service to create a new one, then let the brute attacker into a honeypot with a whole crapload of tantalizing information while you log the evidence.
Normally a brute force attack does not assume that the hacker tries passwords out via the login mechanism. It concerns the case when the hacker already has your hashed password, knows the hashing mechanism used and the salt, and is now down to running different combinations of characters (brute forcing) against the hacker’s own installation of the hash function until a string producing the correct hash output is found - not the login page on the system.
TheDave"Not storing passwords in plaintext is good in theory … access plaintext passwords because the APOP and CRAM-MD5"
Side stepping the discussion slightly –
Both APOP and CRAM-MD5 are horribly insecure… You are only fooling yourself if you deploy a security solution based on these protocols.
If you read POP3 “Security considerations”, it is painfully obvious that no one even took five minutes to think about what to write there. It is just a short section of wishful thinking. http://www.ietf.org/rfc/rfc1939.txt
The APOP way of doing things known to be insecure in 1995, http://citeseer.ist.psu.edu/433722.html
… why POP3 RFC fail to mention this, or why APOP hasn’t been deprecated yet, who knows?
APOP being being way too insecure has been discussed since at least 2001, and those discussions didn’t even include MitM nor rainbow tables. I wager the knowledge about this was known far longer back by the experts.
Today when rainbow tables are being deployed, digest authentication without additional security mechanisms are a laugh.
http://www.ietf.org/rfc/rfc2069.txt is an excellent reference of how to push digest authentication from “horribly insecure” to “good enough for our needs”;
Quality of Protection modes introduce client nounce and client counters into the scheme digest to stop choosen plaintext attacks (however, the vulnerability will continue to exist until browsers stop MitM attacks by rejecting any
Servers can choose if they want to store cleartext or HA1 hash.
It’s really simple, Joe User puts his password in wrong 3 times and his password is locked, changed,
An attacker is likely to convert your account lockout setting into a denial-of-service attack, by locking out every account on the system. And a scheme like this is a massive burden on the helpdesk.
A middle solution may be to temporarily (say one minute) lock out the user with the appropriate message.
Nobody has mentioned one time passwords yet. Seems odd?
SSL certs are great in conjuction with a password but not really the answer. For a reasonably secure site, just go for SSL between client and server (no sniffing, spoofing, man in the middle, proxying etc) and use a password + salt combo in the DB with a password complexity requrement.
If you want to take it further, use pin + one time passwords with SSL and spend some money on RSA, Cryptocard etc.
“If the salt is random, how do we reliably generate the same salt value the next time the user logs in?”
Bob - This is how I do it:
(for example purpose, I’m use plain text)
salt = asaltvalue (this will be a random string of fixed length)
password = apassword
password hash = sha1(salt+password)
password value to store in DB = password hash + salt
Conceivably, if someone were to see the password in your DB, they wouldn’t know if the salt is part of the password, or if the password is just a hash of something. Even if they had some idea that the salt is part of the password, they wouldn’t know the salt length. So in effect, your masking the salt in the password. To compare input password with password in DB, do:
password in = apassword
salt = last 10 characters of the password value in DB
password hash = first 40 characters of the password value in DB
is sha1(password + salt) = password hash?
YES - do something
NO - do something else
password value to store in DB = password hash + salt
Conceivably, if someone were to see the password in your DB, they wouldn’t know if the salt is part of the password, or if the password is just a hash of something. Even if they had some idea that the salt is part of the password, they wouldn’t know the salt length. So in effect, your masking the salt in the password.
In general, this is silly. Just a false sense of security. It is only providing obfuscation in the database. If the code is compromised, they’ll easily see the concatenation and salt length. It will also cost you performance with all the concatenation and splitting.
Does anyone have any suggestions for how to protect your data at rest while allowing code transparency? This is especially a concern for free and open source software (FOSS), as well as distributed systems.
Is username, salt, hash(password + salt) with a strong algorithm and large keys good enough?
Client encryption seems to be workable, albeit with inaccessible JavaScript: http://clipperz.com. In essence, the user is even shielded from malevolent server admins (I would never …).
I’ve experimented with password-protected services/daemons, where a system admin has to enter a password to start the web service. This password is used in the cryptography services, so that there are no secrets in server configuration files or code. Trouble is server restarts are extremely manual. There are still some forensic issues with holding secret information in memory, but it’s not as bad as disk/backups.
So then, in short, the password hash you store in the database should be: hash = md5(sitewidesalt + username + password).
The sitewide salt is there to lengthen the plaintext that is hashed, and if that remains secure then each individual hash is several orders of magnitude harder to crack (read: near impossible).
The username is there to defeat rainbow-table attacks - cracking one hash gives you no benefit whatsoever in attacking other hashes.