I'm making a registration form, my only doubt is how to handle passwords (how to insert them into MySQL database). I don't have the slightest idea on how to do it, what type of column must Passwords be, whether I must encrypt them somehow, etc. Could you provide a basic example with explanation so that I manage to do it?
You don't want to store the password as-is in plaintext. You don't even want to be able to know what the password is. Therefore, you store a hash of the password in your database. When the user wants to log in, you hash the password he's trying to login with, then compare that to the hash in the database. Any serious password storage system furthermore salts the hash to prevent rainbow table attacks against the password (google that). Since this is a rather complex topic and you apparently have no experience with it at all, I recommend you use phpass to hash and salt your passwords without worrying about the implementation details. The phpass site also has some good introductory articles about the topic. Here's another one that keeps it really simple.
As for the database, that'll just be a normal VARCHAR field long enough to hold the hash.
Read this: http://codahale.com/how-to-safely-store-a-password/
Then do this: http://www.openwall.com/phpass/
You should not store password, password hash only.
Database type should be choose after you will choose hasfunction.
For md5/sha512 it will be char(32) if you will keep hex representation
Query is something like this:
"INSERT INTO users SET otherFields,pass_hash='".hashFunc($_POST['password']."';
where hashFunc generates hash ex
function hashFunc($pass){
$salt='something';
md5($salt . $pass);
}
The only way to safely secure a password is using a Moore's Law-defeating hash function. Use bcrypt!
One of the ways it can be done is by using md5. You convert the password to md5 and put it in the database (md5 encryption is one-way) when the user logs in again you convert the filled in password again and check if the converted password is somewhere to be found in your database (in combination with a username usually).
EDIT
You can make a string into an md5 string with this:
$converted_pass = md5($unconverted_pass);
However you will need to add a so called salt-key to the password before you encrypt it with md5. This is a set of letters/numbers etc. If you do this every time you will have the same result but it will be quite safe :)
Related
I am training to secure the login process.
I have used sha 256 in the sign_up.php:
$username= check_input($_POST['username']);
$password= check_input($_POST['password']);
//the password is encrypted in sha256
$secure_sign_up_password = hash('sha256', $password);
and then of course in my users table in my SQL database, I can read:
in the column 'login' the actual typed login
example: if somebody type 'michael', I will see 'Michael' in the SQL database
in the column 'password' the actual typed login
example: if somebody type 'fruit', I will see the hashed value like 'e8bfab56c53980cd014206c8da2f8c9b9708eaacc61' in the SQL database
My question is simple but maybe a bit naive (I'm a newbie): I thought that I could still be able to read the actual password somewhere in my database and that hashing was only made to protect the password from getting intercepted and read while it was being sent. I never know, somebody might ask me to send him his real password. But the only thing I can see is the 'hashed' one in the password column.
Is it made to be like this?
Is it possible to visualize also the real password?
If you would be able to "decode" those passwords, it wouldn't be a very safe system. Once someone gained access to your database - they would be able to gain access to every ones passwords without them knowing...
If you have ever forgotten a password for a site (and we all have - don't deny it!), you'll recall that they usually* don't simply send you your password (in plain text) as a reminder to your email - they'll give you the opportunity to reset it. This way (verifying usually through your email/phone number) they'll know that you are indeed the person who opened the account.
* If they send you your password in plain text that probably means they are storing it like that or in some other easily decrypted form. This site is most likely not as secure as they would like to think...
If you are interested in leaving yourself a "backdoor" of sorts to be able to access any of your users accounts, what you might think of doing is having a special login form from inside your administrator account, that allows you to use the encoded password to log in. That means that you simply leave out the hash('sha256', $password) and pass the $password already encoded (which you extract from your database). It's a bit hacky, and if you already have an administrator account then there wouldn't be much use to be able to log in as a different user because you are already all powerful!
This is by design. Nobody should know what my password is, except for me. Even you as a (insert fancy title here) should not know my password. If I forget it, that's my problem, but your site should offer me a way to reset it. Then when I reset, your site should store the hash once again. The plain-text password should never be stored anywhere.
Never never never hold password in open format in database. If someone find exploit in system, he will be able to make any sql query and get users passwords. And hacker will be able to login into system as user, because he knows username and password
If user want restore password, make functionality for regenerating password. Never store password in plain text.
SHA256 is hash function. Mathematically it means - data can be "hashed" only in one way. I mean, that from hash you cannot restore data. You can read this http://en.wikipedia.org/wiki/Hash_function about hash functions and this about http://en.wikipedia.org/wiki/Sha256 sha256
Result: If someone crack you database and get username and password, he is unable to login into system. Because hacker have only hash data and can't get exactly password for login.
As i mentioned before, hash function can be "hash" data only in one way. But some hackers build VERY big data massive for some predefined algorithms. I mean, that they build hash tables for passwords. Such hash tables looks something like this:
password hash
------------------
a some_hash1
b some_hash2
... .....
qwerty some_hash3
some_data some_hash3 -- yes, data can have collisions. See wiki about hash functions
And if hacker hacked you database and have such table, he able to restore password. For example, hacker get for admin user hash "some_hash3", then hacker search such hash in hash table, find that hash "some_hash3" have password "qwerty" and "some_data" and hacker will try to login with such passwords.
Result: Use salt. For nowadays hackers have such tables for 6 symbols passwords. But you can "suck" them in very simple technic: When you store password in database, add to password some value (salt) and get from such value hash:
// somewhere in code, where creating/updating users password
$password = hash('sha256', $salt.$password);
and when you will check password, use the same logic
Thanks
sha256 hashes and other hashes are one way. See http://en.wikipedia.org/wiki/Cryptographic_hash_function. If you want to be able to decrypt what you write in the password fields in your database, you might want to use another approach.
Instead of creating a hash, you could encrypt with a key, that you do not share with your users. Look at http://www.php.net/manual/en/book.mcrypt.php. The key would be part of your code though, as it's symmetric encryption.
To do it really safe, try real PKI encryption (encrypt with a public key, decrypt with a private one). Look at php.net/manual/en/function.gnupg-encrypt.php or php.net/manual/en/book.openssl.php.
But as other here have said, such things are reasonably NOT done ;)
Hi guys recently I started using
$salt = $uniqueSalt;
$cryptpassword = md5($salt.$password);
How would I convert all password in my mysql database with this so it doesnt affect the users?
the passwords in my database atm are in plain text, I want to convert all the plain text passwords to md5 with the salt
I recommend you read more about salts and how to use them. They should not be a constant string, but something unique to each user. For example username. Or my personal favorite: registration date (with the precision of 1 second, of course).
Also, if you store the passwords in your DB as MD5 hashes, there's no way to convert the passwords. MD5 is one way hashing, you can't obtain the original passwords in order to apply the salt and rehash. If you absolutely want to apply this, then the only way you can do this is force each user to change his password and apply the new algorithm when they do. There are 2 problems with this:
most users are not going to like this
you must keep track of which user made the change and which didn't. This is to prevent problems when logging in.
just like this, but you have to change your login, so you dont check for their password but for md5($salt.$password);
but as my forposters said, its not much securer and if the password isnt already plain in your database you probably wont get it as plain text if it has been hashed
I have some doubts about the best way to do a database with passwords. I need encryption in the passwords, but if i use MD5 i can't recover the pass, isn't it?
And the base64 encoder ? it is secure? with this encryption the recover isn't more a problem.
Suggestions? what is the best way? e prefer a solution that permit to remember the old pass, and not define a new one password.
Thanks!!!
If anybody know a good tutorial about secure passwords in a database i really appreciate that
if i use MD5 i can't recover the pass,
isn't it?
Indeed, if you hash your password using md5 or sha1 (adding a salt is a good idea, btw), you will not be able to recover the password ; and that's the goal of doing so !
The idea is if anyone is able to take a look at your database (be it some evil doer, or one of your employees -- who can be an evil-doer), he will not be able to find any usefull password.
what is the best way? e prefer a solution that permit to
remember the old pass, and not define
a new one password.
The best way is to do the opposite of what you want : not allow one to get his old password -- and develop some way of generating a new password.
This way, you will ensure that no-one is able to get a dump of your logins and corresponding password ; which will make your service safer for your users (especially considering that many people use the same login/password couple of several websites).
MD5 is not used for encryption (which implies that it can be decrypted) but rather for message digestion/hashing. Base64 is also not encryption but rather encoding, which can be decoded with no effort.
There is usually little point in storing encrypted passwords in a database if they can be easily decrypted.
The secure approach is to store only hashes and compare submitted passwords to stored hashes after hashing them on the fly.
You should be doing something along the lines of:
$salt = 'some2%string!!here1';
$hash = sha1( $salt . $_POST['password'] );
to create a hash of the password. You store that hash in the database. When a user wants to log in, you take his submitted function, hash it using the same process, and compare to the hash in the database. If they match, the password is correct.
First off, there's a Significant Difference Between Hashing and Encryption. I suggest that you give that a read before going on...
Now, as to your exact question, there are a few ways to go about it.
Encrypt your passwords with a strong cipher so that you can decrypt them when necessary. A solution such as the one in this post may work for that. However, please note that this isn't a great idea, since if your system is ever compromised, all the passwords will be leaked (never a good idea). There are very few use-cases where it makes sense to store them encrypted, but if you absolutely must, please use a strong cryptographic encryption routine to do it...
Store your passwords using a strong one-way hashing method. No, md5($password) is not good enough. But neither is sha1($salt . $password). The first is trivial to lookup most passwords, and the second can be brute-forced in a reasonable amount of time by simple trial and error. Instead, stretch your passwords iteratively. The best way is to use the standard PBKDF2 function to generate a strong one-way key from the password.
As far as how to recover if the user forgets a password, don't worry about it. If the user forgets his password, create a new one and give that one to the user. It's the industry standard way of dealing with forgotten passwords (Heck, both Windows and Mac do it that way). You may think that you're doing your users a favor by sending it to them, but all you're doing is turning off anyone who has a clue about security from every using your application (and making a lot of people mad if you get compromised).
base64 isn't "encryption". It's intended to convert binary data into a format that's safe for transmission through potentially "broken" email systems that can't process 8-bit binary data properly. It's a best the equivalent of a cereal box decoder ring.
If you want encryption, there's AES, DES, and various other functions available. Problem is, if your code can decrypt the password, the it's trivial for an attacker to figure out how you do it, and/or subvert your code to do it for them.
Passwords should never be stored in a format where the plaintext can be retrieved. If a user forgets their password, you wipe out the old one, generate a new temporary one, and force them to change this temporary password to something else on first login.
You should not ever need to remember the user's password - to do so is a violation of their trust and presents a security hole.
Normally you will hash the password with MD5 (these days it's better to use SHA-2), and when the user submits their password to try and log in, hash that password as well, and see if the hashes are a match.
For added security, you can create a "salt" column to the database and generate a random salt when the password is first submitted. Add the salt to the beginning of the password, and then hash it. Store the hash of the salt+password, and the salt together. Now when the user submits his password to log in, you would combine it with the salt, hash it, and check if the hash is a match.
The salt ensures that if multiple users have the same password (chances are they do), their password hashes will not be identical.
If the user forgets their password they will have to provide a new one, simply storing their password and sending it back to them when they forget is bad practice and a sign to the user that you aren't handling their privacy very well.
As mentioned, use a hash instead of encryption when saving passwords. I generally don't use a random salt since this means an extra field in the DB so that you can authenticate the user. The simplest solution is to use the password as the salt as shown below. Easy to use and easy to authenticate.
$salt = $_POST['password'];
$hash = sha1( $salt . $_POST['password'] );
Stop now and read this. Then go find an open source library to do user authentication. I'm not a PHP dev, so I can't refer you to one, but I'm sure they exist. They'll have had the security holes found already.
Also, for passwords, you should be looking at bcrypt or similarly slow hash functions for passwords anyways, instead of using a fast hash algorithm like MD5 or SHA.
I have a very basic logon system, that authenticates users by the means of a user table in a mysql database with php.
can someone explain what the point of hashing passwords it, how to do it with php, and what is actually stored in the database.
Thanks
can someone explain what the point of
hashing passwords it,
The point of hashing passwords is for security purposes. If inserted as plain text, anyone that gets into your database will now have all of your users passwords. Another huge problem that stems with this is that it more than likely compromises the user everywhere, not just your site, as most people tend to use the same password everywhere.
how to do it
with php, and what is actually stored
in the database.
To use it in PHP you simply take a string, in this example $password = 'password'; and use the command sha1();. This will return something like d0be2dc421be4fcd0172e5afceea3970e2f3d940. It is also good practice to 'salt' passwords with your php script, so that the PHP script login script is required to successfully log in. Example:
<?php
$salt1 = '2348SDasdf!^*__';
$salt2 = '_a35j#*#(lsdf_';
$password = sha1($salt1.$_POST['password'].$salt2); // d0be2dc421be4fcd0172e5afceea3970e2f3d940
?>
Then insert $password into your database. Upon logging in, you would need to salt the password given run it through sha1 in order for it to match the password in the database. You insert it into the database just like any other string, just make sure you have sufficient length granted to the column you're attempting to insert too.
Say someone breaks into your system (or finds a loophole in your sql queries) then you don't want them to know all passwords.
So you hash them before storing them. So you can check if the password is ok, but not deduce the password from the hash.
Unless you use a weak hash. If you would only sha1($password) then you will find putting the hash of often-used passwords into google gives the password in under 0.1 sec.* (but otherwise you could also find rainbow tables for all kinds of hashes)
So you want to add a "salt", that means, you generate some garbage value:
$salt = rand().rand().rand();
and then store
$hash = $salt."-".sha1($salt.$password);
on checking, you know the salt and you can check if the password is right, but knowing the hash and salt makes it still hard to recover the password. (unless you have a rainbow table which includes the salt, of course)
* this needs some explanation: I once took a large user table and found some hashes to appear multiple times. I googled the most-occurring one and it reversed to computer
A hash is a "one-way function". You feed in a password and get an approximately unique output that cannot be (computationally feasibly) converted back into the real password. Depending on the hash, it will look different. For instance, with sha1 (http://php.net/manual/en/function.sha1.php) you will always get a string 20 bytes long.
The benefit is that the real password is never stored in plaintext. To verify the user's password, you just compute the hash on the supposed password and compare it to the stored hash. If somebody gets a hold of your password database, they still don't have the actual passwords.
Noone has said why yet, so let me: most users are idiots and use the same password everywhere. You don't want a hacker to break into your system, grab the passwords then go and hack your users accounts everywhere else.
I am connecting to a MySQL database with PHP and the CodeIgniter Framework. I want to store my passwords encrypted in the database and would like to know the best way to do this.
From a high level overview - don't encrypt, hash. And if you can, use BCrypt. Here's a long article explaining why BCrypt and why hashing.
Encrypting the passwords is a bad idea. If somebody gets your database, they're probably going to get the key you used to encrypt the passwords as well.
The real solution is to hash, salt, and then store the passwords. Jeff Atwood has an awesome post on this:
http://www.codinghorror.com/blog/archives/000953.html
And here is one discussing "rainbow tables," massive tables of words with their MD5 sums:
http://www.codinghorror.com/blog/archives/000949.html
The best way, in that it is both easy and secure, is to use phpass. If your PHP installation does Blowfish, it uses bcrypt; if it doesn't, it uses multiple passes of md5. Either way, it's more secure than straight md5 or sha1.
$hasher = new PasswordHash(8, false);
// Before storing a password
$hash = $hasher->HashPassword($password);
// To check a password against a hash
if ($hasher->CheckPassword($password, $hash))
// $password and $hash match
I always md5sum passwords before I put them into the database, and then also md5sum password login attempts to check them against the db. Just for safety, I do a select query using a where clause with userID (username) AND md5summed password so that I don't get any rows back at all unless both match.
Also, mysql interanlly uses md5summing on it's passwords if you need a level of trust in this method of password obfuscation.
Use a hashing function; MD5 will do fine. Don't store the password, store the hash. Then, to log users in, hash the password they entered and compare it to the hash in the database; if the hashes match, they're legit.
Also, add a salt to the password before you hash it. This can be easy as just appending a string to the password, like your domain name or some other data that's unique to your app. This prevents hackers from using rainbow tables against your hashes.
Never store passwords. Use a one way hash and store that.
hmm, I hash, more than once based on whatever math springs to mind at the time of writing the storing and validation of passwords
From here on I'll probably go with OpenID as much as possible wherever I have an actual choice tho, so i don't have to do any password storage at all. That way I can leave passwords up to the experts, and the users already trusted party.
I agree with hashing and salting. I disagree with picking a site-wide hash. Use a different salt for each user to prevent dictionary attacks against all your passwords at once.