I'm building an application using php for server side code, at the moment the customer has a shared server with linux and a mysql database (yes I know it is an horrible solution, but they don't want to spend more money).
The problem is: they asked me to store their email addresses with relative passwords in the application, so they can contact their customers from different addresses without inserting password everytime, but my problem is: how?
I mean, if I use one-way encryption it'll be more secure, but I have to ask password everytime to verify, two-way encryption is more comfortable, but not safe.
Two-way encryption would be the way to do this. If the customer doesn't want to have to insert the password, then the system has to be able to.
But this is okay. Because these are not user passwords. These are system passwords. They can be as complex and difficult to remember as you want, because they are literally never typed by a user. They wouldn't be re-used by the same user on other systems (which is one of the most insecure things about user passwords and why it's dangerous to be able to read them).
The technical concern here is minor, just use a good encryption on the data at rest (the database where the passwords are stored). The actual concern here is one of educating your customer and advising them of how this works. The passwords are retrievable, so they should be as random and unusable as possible.
Related
As the title says I'm trying to use PHP's password_hash function but I know that it is one way hashing so if I use it the password will be unable to be unhashed.
That being said, I want to be able to have an eye next to a password box (like LastPass) within the system that I'm working with that can display the password for admin users of the site but I'm not sure how to do this. Is there a function within PHP or some library that will allow for secure hashing or encryption so that this is possible? Is there another way to do this securely?
I've been looking around stack overflow for a while now just trying to find an answer to this but have to find anything that is close to what I'm wanting to do.
For a quick frame of reference for this. The users of the site can allow for 3rd party companies to login to retrieve files that are being shared with them. The users create the password and share it with the 3rd party. I want to make sure that when the passwords are secured but still allow the users of the site to go back and lookup the password for the 3rd party companies should they forget their password.
... that will allow for secure hashing or encryption so that [displaying the password for admin users] is possible?
You keep using that word. I do not think it means what you think it means. :-)
Password hashing can either be secure or it can be reversible.
The whole point of password hashing is to be non-reversible. If you want the original password, you're going to have to store it (keeping in mind how insecure this actually is).
At a bare minimum, you'd want the plaintext password somewhere totally separate from, and inaccessible to, the outside world. But the ground is littered from the corpses of password files that companies thought were secure from the general public, so my advice is to steer well clear of this.
No, you cannot get the original plaintext password from a hash. That's the entire point. The plaintext password is a secret that only the user is supposed to know. The secrecy of their password is the only security measure they have. If the password is "publicly" known then the security is out of their hands. And if anyone besides them knows the password, even if it's just your server, it becomes harder and harder to control who knows the password and it's only a matter of time until it leaks entirely.
That is why you don't want even your server to know the actual password, and to only store an irreversible hash of it.
If you want to store the password in a way that is reversible, at the very least you should store it such that even the server itself could not see the plaintext. Meaning, even if you encrypt it, encrypt it in a way that the server itself cannot decrypt it. Because if your server can decrypt it, so can anyone with access to that server. For instance, use entirely client-side encryption within the browser and require the user to enter their password in some way which will decrypt the stored password. Of course, this limits who will be able to see the password, which is the entire point.
If you need concrete encryption schemes to design this, it's best to ask at http://security.stackexchange.com or perhaps https://crypto.stackexchange.com.
I am wondering if file_get_contents is secure for passwords with no SSL. I have made a admin panel in PHP and have this method for passwords instead of SQL. Please give a source for your info if possible.
Storing a plain text password in a file and reading it with file_get_contents will work, but your security will be low. More specifically, it will risk your users' security. This is because, even though they should not, some of them will reuse passwords across services, together with the email address that you might also be holding for them.
With that in mind, you should be hashing these passwords, and not holding them in plain text. That means that you'll convert the password to a form that cannot be reversed, and so to check the password, you'll need to hash the one the user enters at login time too. It's a clever way of making it difficult for crackers to work out what the real password actually is, even if they get into your server and steal the password file.
The recommended approach in PHP is to use password_hash, details for which are in the PHP manual. The advantage to this function is that it is deliberately slow, which makes it harder for a potential attacker to 'brute force' guess many millions of passwords.
When handling passwords it is also a good idea to do so via SSL, using a server certificate inside your web server. This makes it harder for MITM (man in the middle) attacks to take place, which can steal a password in transit across the network.
I am developing a website that connects to a users MSSQL database to collect information. Users are assigned to different MSSQL database accounts and connect to them using the IP, username and password stored inside the MySQL DB.
Currently, what I've got is PHP the AES encrypts/decrypts the passwords as needed. That just doesn't seem right. It prevents you from seeing the plain text password by looking in the database (which is undeniably good) but I'm not sold on it's level of security.
Hashing is great and all if you never need the password again, but I do. So I don't really know how to go about implementing a reasonable level of security into this particular aspect of the site.
Any suggestions would be great. Am I completely wrong and being an idiot. Is there a vastly superior way to do this?
Obviously if you are sending the password over to MS SQL, you are going to need to be able to reverse the value. I would think encryption would be the most correct answer here. Either way your code will still be able to extrapolate this password, otherwise you cannot connect.
If you would like to increase the security, you can seed your encryption with a checksum calculated from the user name... however, if the user name ever changes, you will need to decrypt and re-encrypt. This will only make it a bit tougher for "others" that may know you are using AES.
But at the end of the day, you will always be able to know what the password is, since you need to decrypt. There is only so much you can do in this situation, the best would be to demand the password from the user every time it's needed.
I really don't think there is a way for this to be done safely but maybe there is a more outside the box way to approach the task.
I am working on a project management site. Some of these projects would be Websites so the client wants to be able to display the ftp, database and hosting information. This would require me to display username and passwords unencrypted on the web. I obviously see the huge risk in this because if the site gets cracked it has information that could destroy other sites as well.
One way I can think to approach this is encrypting the passwords and then creating an application that they would keep locally on there machine to decrypt that password. This is really the only "safe" way I can think of.
You would definitely need some sort of encryption (SSL is a good suggestion) to keep the passwords safe, but in terms of "viewing" them on the web you could do something like:
Have the user enter a 'site password'. You could also use a captcha to prevent bots from getting at your passwords. This will allow them to view their own password for a short period of time, say 10 seconds. Their password would be displayed in an input box, or some sort of box, that would be readonly. They should not be able to copy/paste passwords.
Having username and password information up on the screen is definitely a security risk, but this all depends on how security sensitive your information is going to be.
Another solution could be that if they need to view their password, they are required to change it the next time they log in. This will allow them to view their current password, but will negate the security risk of having that password stolen since they would be resetting it almost immediately.
All of this depends on how sensitive the information is of course.
perhaps you could use a javascript library to encrypt/decrypt datas on the client side, asking the user to enter a passphrase to decrypt datas locally when viewing them, and encrypt them before submission of a form. This way only crypted datas will transit over the network and wihtout the passphrase you only access crypted datas.
Start with SSL for the secure transit.
Encrypt the information before storing it.
Read some articles on how hackers get into these sites, plug the holes before you learn a difficult lesson.
NEVER display a password, you don't need to. Use a login link, where you can include tokens and checks that ensure the user clicking on it has the appropriate permission level.
Example: Employee gets fired. He is upset captures the screen with all of the passwords on display. Not a great situation for your company or the former client.
Using my method, the user could capture the screen, copy the links, it would have no effect, as his token would be revoked and the link wouldn't work. Your client site is safer this way.
The simplest and safest way to do this would be to use SSL.
If you can't go that route than you'll need to come up with your own way of encrypting the information during transit. This is difficult. You'd need something like a Diffie-Hellman key exchange (http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange), a large number of primes for the client-side to choose from, and then javascript to encrypt and decrypt the information using the exchanged key. You could improve on this by having pre-cached the javascript, downloading it from a third party, and (preferably) doing a checksum to ensure that you JS hasn't been modified.
However, since the encryption code and primes are sent plain-text through the internet, they could be modified en route allowing an attacker to manipulate where POSTs will be sent and how information will be encrypted.
In short, if you're not using SSL, you have not way to guarantee that information is transferred securely.
One thing you might do is tap into PGP. If the user uploads their public key, you'd be able to return messages to them safely. This is because the PGP software is independent of the browser/internet.
How do I write/put together a secure login in PHP? The website developer guide said I shouldn't roll my own, so referring to samples available via Google is useless.
How do you pros do it? Lets say you're building a world-class app in rails, would the same libraries / techniques be usable here?
Thanks
In Rails, one would generally use a pre-existing library. Authentication is easy to do wrong, and the problem's been solved so many times that it's rarely worth the effort to solve it again. If you are interested in writing your own implementation, then I'll describe how modern authentication works.
The naive method of authenticating a user is to store their password in a database and compare it to the password the user submits. This is simple but unbelievably insecure. Anyone who can read your database can view anyone's password. Even if you put in database access controls, you (and your users) are vulnerable to anyone who hacks around them.
Proper form is to use a cryptographic hash function to process the password when it is chosen and then every time it is submitted. A good hash function is practically irreversible -- you can't take a hash and turn it back into a password. So when the user logs in, you take the submitted password, hash it, and compare it to the hash in the database. This way, you never store the password itself. On the downside, if the user forgets their password, you have to reset it rather than send it to them.
Even this, however, is vulnerable to certain attacks. If an attacker gets hold of your password hashes, and knows how you hash your passwords, then he can make a dictionary attack: he simply takes every word in the dictionary and hashes that word, keeping it with the original. This data structure is called a rainbow table. Then, if any of the dictionary word hashes match a password hash, the attacker can conclude that the password is the dictionary word that hashes to that password. In short, an attacker who can read your database can still log in to accounts with weak passwords.
The solution is that before a password is hashed, it is combined (usually concatenated or xor'd) with a value called the salt which is unique to each user. It may be randomly generated, or it may be an account creation timestamp or some such. Then, an attacker cannot use a rainbow table because every password is essentially hashed slightly differently; he would have to create a separate rainbow table for every single distinct salt (practically for each account), which would be prohibitively computationally expensive.
I will echo the advice of the other answerers: this is not simple stuff, and you don't need to do it because it's been done before, and if you do it yourself you stand a very good chance of making a mistake and inadvertently compromising your system's security. But if, for whatever reason, you really, really want to write one yourself, I hope that I have provided an (incomplete!) outline of how it's done.
The Zend Framework has an 'Auth' module which would be a good place to start. Or, if your site will be hosting an install of WordPress or PHPBB, there are ways of leveraging those technologies' authentication modules to sign in to other pages of a site.
One thing to look at when you are trying to authenticate is what is your real goal.
For example, on SO I use my google login, and that works, as they just need to know who I am, and they can trust that Google has an idea. So, if that model will work for you, then look at using OpenID, as there are various tools for that.
If you must do your own, then there will be various tests to ensure that it is secure, again, depending on how paranoid you want to be.
Never trust anything from the user, unless you have used some strict verification.
Use https to help protect the password of the user, you owe them that much.
I will end my response here as Thom did a fantastic response.
by Soulmerge:
I think the accepted answer in your other question states it pretty well. Hash the passwords with a salt. Other than that, there are some security ideas on the transport layer:
Use https when sending passwords. This makes sure nobody can catch them on the wire (man-in-the-middle attack or the client uses an evil proxy)
An alternative is to hash the password using javascript when the login form is submitted. This makes sure that the password is never transported in plaintext. You should hash the hashed value again with a salt on the server. (md5($_POST['postedPwHash'] . $salt))
a good method to somewhat secure the client-server transaction (if no ssl is available) is to use a one-time random key to create a unique hash from the credentials, then only send that unique hash to the server. the server then compares this hash to its own generated hash instead of comparing it to the real credentials. this would provide a good defense against the man-in-the-middle attack. the downside is that to do this the user must have JS enabled (at least i dont know of a good method to encrypt client-side data without it). this means that you will need a sufficient fallback when it isn't on. you can even create the form in JS to make sure its enabled.
this library is a simple library i wrote once that does the procedure i described, though it probably needs some improvements.
note that this is in addition to using "salting" methods and other server-side security measures. it is also quite vulnerable to dictionary attacks as the entire hashing process is by definition procedural, predictable and visible to the user (as JS always is).
My answer is "Don't do it"
This is a very complex area, full of potential security gotcha's. If you are not an expert in this field, then you are really just asking for trouble and problems down the road.
I would recommend looking at getting an existing solution to do. Sadly I don't know any that I would be happy to recommend, other than openid. I'm sure you will get some good suggestions here though...