Is there a safe way to send a user their password in clear text via email? - passwords

If I understand correctly, the biggest problem with sending a password via email is that it requires the password to be stored in clear text in the database. If the DB is compromised, the attackers will gain access to all accounts.
Is there a workaround for this problem?
How can one make sending a user their password via email as safe as possible?

The simple answer is: don't. If you think your database is insecure, an email is far, far less.
If you mean that you want to send them their password when they register, then you could do that before you store it in the database.
If you mean after they have registered, the only option is to store in plaintext (again, don't do this) or make a new, random password and send them that. It is impossible to get their password from the hash, which is why it makes the password storage safer. The best option is to generate a new (temporary) password you send them, or a token giving them access to a password change system.
You may want to consider a good hashing algorithm like BCrypt that includes a salt.

I don't know if my suggestion is feasible for your scenario, but you should better keep the data hashed or encrypted and send password reset links instead of plain-text passwords.

The moment the password is in cleartext in the email, it is inherently insecure.
As such, there is no safe way to send a password in cleartext safely.
You should not be storing passwords in cleartext in your database - you should be using salted hashes. When the user enters their password, you hash it with the salt and compare to the stored hash.
When people forget their password, instead of sending passwords by email, you should send reset links backed up by expiring tokens. These would generate a temporary new password (that would expire within minutes).

You should be hashing all passwords in your database.
sha1($_POST['password'].$salt.$username);
In the case of a lost password
A user requests a password reset link, which contains a hash generated in the "user_meta" table. When the user recieves this link, the hash is compared to that in the database, and the user will be able to UPDATE their current password with a new password.
The PTXT of the password is never reveiled.
You only compare hashes.

Yes, there is a common workaround.
Assuming that you have your users in your database.
You send the "password reset link" containing some "key" information, like a guid. An example link is a form:
http://your.site.com/setpassword?id=5b070092-4be8-4f4d-9952-1b915837d10f
In your database you store the mapping between sent guids and emails.
When someone opens your link, you check your database and you can find out who asks for the page - because any valid guid maps to an email. You can then safely let the user change his/her password assuming their email is not compromised.
When it's about to store the password, you never store it in plain text, you always hash passwords, using additional random salt to make the dictionary attack more difficult when someone breaks into your database.

There is a workaround which is less secure than a password reset but works if it is a requirement that users are sent a password, not a reset link.
What you do is you generate a new password that contains sufficient randomness to be very hard to guess, but is also formatted in a way that it is easy for them to remember and read out (say over the phone).
Something like: xyz-xyz-xyz-nnnn where xyz is an easy-to-spell but uncommon word and nnnn is a four digit number.
Then set it up so that this is a temporary password that needs to be changed on first login.
Set the password using the same logic you would use to set a normal password, so that it is correctly salted and hashed, and then send the password plaintext via email, like so.
Dear FirstName LastName,
You requested we reset your password.
Your new password is:
insipid-mirth-nonplus-9174
You will be able to log into the system once using this password, then you will need to enter a new password.
Important Caveats
This system has some serious vulnerabilities which make it unsuitable for websites where data security is crucial. There are more than these, but these are the ones I know/can think of:
Unlike systems which use a password reset link, this system could be used to lock someone out of the system (assuming you use it as is) unless you either require someone to fill out identifiable information before issuing the password reset, or send a "are you sure you want to reset your password?" email first. This would entail them clicking on a link with a GUID that goes to the server; at that point they may as well be sent to the password reset form anyway.
Since the password is being sent plain text via email, there is a danger it can be intercepted and the password can be used. Although to be fair this is not that much different than the risk of sending a password reset link.
If you ignore the risks in step #1 and you don't use a sufficiently random way of generating passwords (say you use a word list of fewer than 1000 items), someone who has hacked into your server will be able to retrieve the salted password hash and then write an algorithm that generates all possible passwords and checks them against the hashed password. Not as much of a problem if you use a cryptographically complex hashing algorithm.

If you want to send password to user via Email in cleartext and want to store those password into database as hash or any other format . It will be possible.......
Just you will have to follow some simple way....
1 .you will have to take those password as variable which will send from user.
2. When you store database then just convert it as you wishes format.
3. But when you send those to user by mail , That time just sent those variable password...
I think it will be helpful to build your concept about WAY.......

Related

bcrypt hash both email address and password

I'm setting up an anonymous site. So basically a user's account cannot be traced back to any actual person (such as by an email address). Authentication is the part that I'd like your thoughts on. If I use the email/pass combo to authenticate can I use bcrypt to hash both the email address and password (well I know this is possible but is it practical)? I thought if the email is encrypted then it'll be extremely slow to search the db to find a match. Is this true/false? What are your thoughts? Any other ideas? Basically, I'm open to any ideas on how to authenticate, but if it's authenticated with an email then it can't be exposed/or decrypt-able. Thanks!
Once you hash something, the original can never be recovered.
Let's take a password for instance, typically when a user signs up with an email/password you'll hash the password (with something like bcrypt), then store the hash in your database. This is great because if an attacker gets a copy of the database, there's no way to 'decrypt' the hash.
In your situation, you probably WON'T want to hash the email because that means you'll never be able to email the person -- which I'm assuming you'll want to do.
If you decide to go that route, you'll basically just be storing two passwords per user (that's the closest analogy I could come up with, sorry!).
Hope that helps!
EDIT: A better way to do this would be to create a new account given ONLY a password -- and then you generate a username for the person automatically. This is what companies like privateinternetaccess.com do -- they'll generate some random username for you -- this way you can't contact the user, but they can still safely log into your application.
i don't see any problem with your idea (assuming that you never want to asynchronously send email to the user).
login:
user posts a login form that has cleartext email and cleartext password (of course you use good TLS transport encryption)
eh = h(email), ph = h(password)
fetch the record from user database where eh == stored_eh
compare ph against stored_ph
forgot password procedure: in the very moment the user posts the "forgot password" form with his cleartext email address, you HAVE his email. compute eh, lookup profile, generate onetime token, store it into profile and put it into a mail to his email address. he can then use the token to define a new password.
change email procedure: similar to above, you have the cleartext old/new email addrs in the moment the form is posted.
Notes:
the db lookup in step 3 is not slower than using a plaintext search key
for 2 and 4, use some sane code from a well-maintained library (scrypt, bcrypt, pbkdf2, sha512_crypt, not just a simple salted-hash)
if an attacker gets your database and has a list of potential email addrs, he can easily find out whether you have (some of) them as users and determine their user record in your db. if that is a problem, you maybe could use h(email+password), but then there is no password recovery possible.

IBM Worklight. Is it possible to store user credentials securely and recover them without user interacton?

There is a common requirement of storing user credentials securely (user id / user password) in the App and use them automatically next time the App starts, but I'm not being able to figure out how to do this without user interaction.
Using JSON Store I need a password to encrypt the information, so if I store user credentials in the JSON Store I will need to ask to the user for the password used to encrypt the information.
A solution I figure out is to store the user id in a JSON Store without encryption and the password in a JSON Store encrypted with the user id as password. May be this solution provide a bit more security than not to encrypt anything but I think is not a complete solution.
As explained in the comments this is a really bad idea.
Is there any solution to store user credentials securely and recover them without user interaction?
You can use the Keychain API on iOS. Android doesn't seem to have an equivalent API.
The most complete solution I figure out is to store the user id in a JSON Store without encryption and the password in a JSON Store encrypted with the user id as password. May be this solution provide a bit more security than not to encrypt anything but I think is not a complete solution.
I would strongly advise against doing that, if you store the encryption key (the user id) in plain text, then the attacker can simply use that to get to the password.
Update (Aug 27, 2014)
You should consider:
Hashing - You could hash values you want to protect. These are one-way functions, so you can't get the password back once you hash it. However, you can verify that the user provided the correct password. For example: First login you store( hash(password) ) then on next logins you compare if hash(password_provided) == stored_password_hash. If it matches, the user provided the same password. You should also use a salt.
You could give the user the ability set a pin using some library like ABPadLockScreen (you could probably find or implement something similar for Android too). You can then use the pin as the PBKDF2 input to generate an encryption key (JSONStore will do this for you when you pass the pin as the password). I would advise in favor of letting users only try a small amount of incorrect pin numbers, especially if the pin is only numeric and short, that way they can't easily guess the pin by trying various combinations. The idea here is that a pin will be easier to remember and type than their password.
FYI - There's a Stack Exchange site similar to StackOverflow but for security questions here.

How to securely set up cookie-based authentication in classic ASP?

What would be the most secure method of using cookies to authenticate users in a classic ASP website?
I don't want to use the ASP Session object as the session cookie times out after a while, and I'd like the user to be able to keep their login to the website active between separate browser runnings.
However, I don't want to just create a cookie containing their user ID as that could be easily forged - so what are my options here? I guess some sort of encryption but I don't really know what the standard methods of doing this is.
Your options here are pretty much limited.
Get your users to log back in again; best security approach.
This obviously applies much wider than just ASP.
The best way would be to hash the password... you should be doing this in any case where you store it in database.
The hash is a cryptographic function - when you run a string through it (eg password) you get out a long code. If the input is the same, the output is always the same.
But (this is the important bit) its mathematically virtually impossible to reverse the process - to start with the hashed value and work out the password, other than brute force (someone hashes dictionary, or random strings and looks for output that matches the hash they have).
So when the user sets up account, they put in their desired password, but you hash this, and store that. Similarly in the cookie, after they login you store the hash, not the password, and this has is compared with the hash in the db.
The downside is you can't send a password reminder since you don't know the password - to you'd have to send a password reset link and have a system to do that.
If you're really paranoid you might double hash, eg when they login the password is hashed once and stored in cookie. Its then hashed again and compared with the password in db (which is also double-hashed).
Don't Do It
Maintaining a user login quote "...between separate browser runnings" is not secure. IMHO, when you close the browser a previous login should be gone. Suppose your visitor was using a community pc at a coffee shop.
If you maintain this login the potential for the next community user to open the browser, navigate to your website and "poof" they are automatically logged in as the previous user.

VB.Net Password Hashing practices

I'm trying to secure a website that is being moved to a public server soon. I've just finished adding the password hashing functions to all of my login scripts. I'm using FormsAuthentication.HashPasswordForStoringInConfigFile(pw, method) to do so. I have a question about the process I'm using and whether or not it's secure for a web server:
Password is sent in plain text over HTTPS to the server
The server looks in the Users table to find the user's Salt (several random characters) and their hashed and salted stored password
The plain text password is appended with the Salt
The new string is hashed using the above function
The newly hashed version is compared to the stored version
If equal, login is allowed
If not equal, the login attempt is logged in Session variables, up to 3 times before locking out the user's machine from accessing the login page until an admin verifies IP address and unlocks.
Does this look about right? I just don't see how the salt is effective in this method... Anyway, all I've done is add a salt and hash. Is this considered Encryption? Or am I missing a step? I remember reading that hashing algorithms like SHA1 and MD5 are not encyption algorithms, so what else needs to be done?
That is correct. The salt is used to prevent rainbow table attacks where a dictionary of common works hashed with MD5 is used to try to gain entry. Using the salt ensures that even if they had an MD5 hash of the word, it wouldn't work because they don't know the salt.
The MD5 algorithm is a 1 way hash algorithm, and not an encryption value. The difference is, once you've hashed the value, there is no way to get back to the original value. Encryption allows you to decrypt the data and get back the original value. So you are correct, they are not the same, and your passwords are not encrypted, they are hashed. This means that if someone forgets their password, you cannot send it to them. You have to provide a way for them to reset their password instead. This also means that anyone with access to the database would not have access to raw passwords. Which is good because a lot of people use the same password everywhere, and if you had access to a large list of usernames and passwords, someone could decide to start trying to log into bank / credit card websites.
What you are doing is a recommended practice.
You shouldn't be storing the retry count in the session - an attacker could simply discard their session cookie after each attempt, allowing them to retry as many times as they wish. Instead, store it against the user record.

How to implement Querystring authentication

I’m developing a website of a client and they are sending out newsletters to their customers (through the website administration interface)
The newsletters are personal to each of the subscribed recipients/customers.
Each recipient/ customer is also a user with a username/password that enables them to sign in on the website and manage their newsletter subscriptions and participate in the sites community.
This all works like a charm.
Now my client want a “Manage my subscriptions” link in the newsletter email that when pressed automatically signs the recipient/customer in on the website with no need to remember username and password.
This could be easily solved be making a link like this:
http://mysite.com/manage.aspx?user=peter&password=hounddog
Of course information should not be clear text but encrypted in some way.
This however poses a problem since the only way a user can be authenticated on the website if by providing a valid username and password.
In the name of security, passwords are stored as hashed values in the database making it impossible for me to insert the password in the link.
What is the best way to accomplish this without compromising the security?
You will have to compromise your security somewhat, if you want people to be able to login without entering password. Note that even if you had access to the password (as in your example), you would have to embed it in a mail massage which would be transmitted in plaintext.
You can create a Guid associated with each user and message, and append it to the URL, and allow that to login automatically.
You could perhaps isolate the permissions so that a login through a newsletter guid link only allows the user to manage subscriptions, but that a real password-login is still required to participate in the forum. In that case its pretty limited what havoc can be wrecked if someone gets access to a Guid from a mail message.
Could you not insert an encrypted user name bundled with the hash value of the password?
What I mean is, encrypt & encode the user name to always be a particular length or to have a known break character in it then append the passwords hash value. this way, you could break apart the query string easily while still having the user name and password securely encoded. A straight compare of the hash values would be enough, with the unencrypted, decoded user name to allow access.
What about using an encrypted cookie that contains an access token ?
This cookie would be delivered after a successfull authentication by a separate page.
This kind of token can also be part of the URL query string.
Also you might consider using secured https instead of http.