php hashed password creation - php

I am looking to create a commercial website using php and I wanted to make sure the code I have for user hashed password was strong enough to avoid brute force attacks.
Note that my server and it's php version does not support blowfish so I am trying to figure out a decent method of hashing a password.
$pw = "12341234";
$salt = 'randomchars';
$initial = sha1($pw);
$hashed = md5($salt . $initial);
Is there something else I should be considering? any thoughts would be appreciated!

You want http://www.openwall.com/phpass/

I think you are not aware of the fact, that the way you hash passwords does not influence the possibility of cracking the password by brute force attack (eg. when attacker tries to provide thousands of possible passwords). It only makes password safe in case someone sees the value in the database that is used to represent this password.

For Brute Attack you can use google's captcha..
And for code password you can use first md5 and second sha1 because md5 generating 32 characters data sha1 64.. :)

Your snippet seems secure. You want to protect against rainbow table attacks, so the double-encryption is a good idea. The computing power to even generate a list of MD5 hashes of SHA1 plaintext is huge, but it's still no harm to have the salt there to protect against such an attack.

There is no need to reinvent a wheel as there is a crypt function.
// generate MD5-hashed password with salt
$password = crypt('mypassword');
// password contains string(34) "$1$bkZO1nIl$y5bzPPwByq.9tYEb64k4e0"
See examples for different types of hashes including MD5 and SHA256 in the manual: http://php.net/manual/en/function.crypt.php
I this is not enough, there are alternatives:
How do you use bcrypt for hashing passwords in PHP?
Keep in mind that if someone was able to lay his hand on your database, his ability to crack users' passwords will be least of your problems.

Related

Best way to store passwords in MYSQL database [duplicate]

This question already has answers here:
Best way to store password in database [closed]
(8 answers)
Closed 10 years ago.
Yes I know storing passwords in plain text is not advised.Is there a best and easy way to store passwords so that the application remains secure ??
First off, md5 and sha1 have been proven to be vulnerable to collision attacks and can be rainbow tabled easily (when they see if you hash is the same in their database of common passwords).
There are currently two things that are secure enough for passwords that you can use.
The first is sha512. sha512 is a sub-version of SHA2. SHA2 has not yet been proven to be vulnerable to collision attacks and sha512 will generate a 512-bit hash. Here is an example of
how to use sha512:
<?php
hash('sha512',$password);
The other option is called bcrypt. bcrypt is famous for its secure hashes. It's probably the most secure one out there and most customizable one too.
Before you want to start using bcrypt you need to check if your sever has it enabled, Enter
this code:
<?php
if (defined("CRYPT_BLOWFISH") && CRYPT_BLOWFISH) {
echo "CRYPT_BLOWFISH is enabled!";
}else {
echo "CRYPT_BLOWFISH is not available";
}
If it returns that it is enabled then the next step is easy, All you need to do to bcrypt a password is (note: for more customizability you need to see this How do you use bcrypt for hashing passwords in PHP?):
crypt($password, $salt);
A salt is usually a random string that you add at the end of all your passwords when you hash them. Using a salt means if someone gets your database, they can not check the hashes for common passwords. Checking the database is called using a rainbow table. You should always use a salt when hashing!
Here are my proofs for the SHA1 and MD5 collision attack vulnerabilities:
http://www.schneier.com/blog/archives/2012/10/when_will_we_se.html, http://eprint.iacr.org/2010/413.pdf, http://people.csail.mit.edu/yiqun/SHA1AttackProceedingVersion.pdf, http://conf.isi.qut.edu.au/auscert/proceedings/2006/gauravaram06collision.pdf and Understanding sha-1 collision weakness
Hashing algorithms such as sha1 and md5 are not suitable for password storing. They are designed to be very efficient. This means that brute forcing is very fast. Even if a hacker obtains a copy of your hashed passwords, it is pretty fast to brute force it. If you use a salt, it makes rainbow tables less effective, but does nothing against brute force. Using a slower algorithm makes brute force ineffective. For instance, the bcrypt algorithm can be made as slow as you wish (just change the work factor), and it uses salts internally to protect against rainbow tables. I would go with such an approach or similar (e.g. scrypt or PBKDF2) if I were you.
Store a unique salt for the user (generated from username + email for example), and store a password. On login, get the salt from database and hash salt + password.Use bcrypt to hash the passwords.
Passwords in the database should be stored encrypted.
One way encryption (hashing) is recommended, such as SHA2, SHA2, WHIRLPOOL, bcrypt
DELETED: MD5 or SHA1. (those are older, vulnerable
In addition to that you can use additional per-user generated random string - 'salt':
$salt = MD5($this->createSalt());
$Password = SHA2($postData['Password'] . $salt);
createSalt() in this case is a function that generates a string from random characters.
EDIT:
or if you want more security, you can even add 2 salts:
$salt1 . $pass . $salt2
Another security measure you can take is user inactivation: after 5 (or any other number) incorrect login attempts user is blocked for x minutes (15 mins lets say).
It should minimize success of brute force attacks.
best to use crypt for password storing in DB
example code :
$crypted_pass = crypt($password);
//$pass_from_login is the user entered password
//$crypted_pass is the encryption
if(crypt($pass_from_login,$crypted_pass)) == $crypted_pass)
{
echo("hello user!")
}
documentation :
http://www.php.net/manual/en/function.crypt.php
You should use one way encryption (which is a way to encrypt a value so that is very hard to revers it). I'm not familiar with MySQL, but a quick search shows that it has a password() function that does exactly this kind of encryption. In the DB you will store the encrypted value and when the user wants to authenticate you take the password he provided, you encrypt it using the same algorithm/function and then you check that the value is the same with the password stored in the database for that user. This assumes that the communication between the browser and your server is secure, namely that you use https.

Codeigniter: Is encrypting a password like this secure?

I was wondering if someone could me some advice please? I was wondering how secure/insecure or otherwise rubbish the following code is for encrypting passwords using Codeigniter?
$safe_password = sha1($password, $config['encryption_key'])
If not secure can people give me some tips to make it more secure using Codeigniter please?
Many thanks :)
sha1 has been know to be vulnerable to collision attacks, try using bcrypt as it's one of the best. If bcrypt doesn't work for you use sha512 and add a salt too.
bcrypt may seem daunting to use but here's an article on why you should use it: http://phpmaster.com/why-you-should-use-bcrypt-to-hash-stored-passwords/
The reason why sha1 is unsecure is because of collision attacks, here is one of the papers where it exposes sha1's security risks: http://www.schneier.com/blog/archives/2005/02/cryptanalysis_o.html
If you would like to use sha512 all you need to do is:
hash('sha512', $password.$salt);
And make sure you always use a salt or else some one can use a rainbow table (database) to see if your hash matches a common password inside the database.
Hashing algorithms such as sha1 and md5 are not suitable for password storing. They are designed to be very efficient. This means that brute forcing is very fast. Even if a hacker obtains a copy of your hashed passwords, it is pretty fast to brute force it. If you use a salt, it makes rainbow tables less effective, but does nothing against brute force. Using a slower algorithm makes brute force ineffective. For instance, the bcrypt algorithm can be made as slow as you wish, and it uses salts internally to protect against rainbow tables. I would go with such an approach or similar if I were you.
From PHP DOC
string sha1 ( string $str [, bool $raw_output = false ] )
If the optional raw_output is set to TRUE, then the sha1 digest is instead returned in raw binary format with a length of 20, otherwise the returned value is a 40-character hexadecimal number.
My Advice use BCRYPT its more secure for easy implementation you can try password_compat
Example
$hash = password_hash($password, PASSWORD_BCRYPT);
No, sha1() is not considered secure as can be read, for example, here:
http://www.php.net/manual/en/faq.passwords.php#faq.passwords.fasthash
Currently, a good choice might be SHA512 using a salt: hash('sha512', 'text+salt')
Better solution is with bcrypt, have a look at this tutorial.
Here is a small library that you can use with Codeigniter https://github.com/waldirbertazzijr/codeigniter-bcrypt
Another related question.

Md5 salt password php

I know that there are alots of questions about this subject but i really need to ask this.
Today I've been working on encrypting passwords with md5.
So what I've done is.
I got 4 salts. (they changes depending on user values)
from email id and substr then md5 them
from email and id substr other positions
a long string, substr it and then md5 it
another long string, substr it and then md5 it
Then i md5 salt1 and 3 and the password with salt 2 and salt4
After this I have to change the password automatically whenever a user changes his email or his id getting changed.
What do you guys think about this?
Nothing.
MD5 is broken and bad.
Using the mailaddress as salt is a good idea. But using md5 is not. Use instead bcrypt, scrypt or pbkdf2.
Don't invent your own ecryption, unless you really know what you are doing, and trust me, you don't
First, let us define a few terms.
Encryption is when you encode a message so that it cannot be read. Encryption involves a plaintext, a cipher and a key. It is like putting a book (the plaintext) in a locked room (cipher), which can only be opened using a known tool (a key). There are many kinds of encryption, but that is a simple description. Encryption is two-way, meaning that you can encode and decode the message.
Cryptographic hash is when you take any kind of data and generate a fixed size value for it (usually called a hash or a digest). Cryptographic hashes are one-way, which means that you cannot reverse the process.
A salt is a unique string, or a collection of bits, similar to a nonce (a unique number that is only used once). Salts are only used to make it infeasible for a cracker to process a list of hashes. They are not supposed to be used as a secret (i.e. like a cryptographic key). The only reason people usually talk about randomness when it comes to salts is because they want to generate a unique salt (if the randomness is not great enough they may get colliding salts, for instance).
Okay, now to how you should hash a password.
A relatively safe way of hashing a password is to simply tack on a unique hash onto a password, and then save the salt with the password:
$pass = 'this is my password';
$salt = uniqid('', true);
$hash = sha1($pass . $salt);
// INSERT INTO users ('hash', 'salt') VALUES ('$hash', '$salt') WHERE ...
That is an okay way of doing it if your website does not retrieve any sensitive data from its users.
If you deal with sensitive data, or if you just want to make sure that you are doing everything you can to keep stuff safe, then there is a PHP function that does the hashing for you. It is called crypt() (read the documentation to learn how it works). Here is an example of how to hash a password using the function:
$pass = 'this is my password';
$salt = 'unique string';
$hash = crypt($password, '$2y$07$'.$salt.'$');
echo $hash;
That will securely hash a password.
The thing to realize is that the crypt() function is much more secure than anything you can come up with (unless you are a specialist in the area).
In newer versions of PHP (5.5.0+) there is a password hashing API that makes it even simpler to hash a password.
There are also various hashing libraries out there. PHPass is a popular one.
It is bad, because it uses MD5.
MD5 is a very fast operation. It can be executed billion of times per second on graphic cards hardware. It is considered bad practice to use it for any password related things.
Use bcrypt. Use a random salt. Use the upcoming PHP API for hashing, verifying and rehashing passwords. This include file implements it for versions starting with PHP 5.3.7: https://github.com/ircmaxell/password_compat
Well, "MD5 is broken and bad" is a little exagerated. Even if it can be brute-forced with a lot of CPU, it is not "broken" and is still a very useful algorithm for a lot of things involving hashing.
So "MD5 should not be used for password encryption" sounds much better to me.
When using PHP, an easy and safe option is to rely on the password_hash() (which natively generates a random salt) and password_verify() functions.
The advantage is that the encryption algorithm will transparently be updated with each new PHP version (at the moment PASSWORD_DEFAULT is set to bcrypt, but should bcrypt be "broken" it can be set to a newer algorithm), which makes any code using those functions quite resilient.
I personally do not recommend involving of the user id and his email into the hashing of his password.
You can deal with the password by:
Dynamic salt per user based on random string generated on user registration
Prepend one part of the salt and append the other around the password
Double md5: md5(md5($password))
Etc.
a simple way would be to generate a random salt for each user and hash your password like this
public function encodePassword( $raw, $salt ) {
return hash('sha256', $salt.$raw);
}
For high security hash, you can check this link which explain how to implement PBKDF2:
http://crackstation.net/hashing-security.htm#phpsourcecode

Username, Password, Salting, Encrypting, Hash - How does it all work? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Secure hash and salt for PHP passwords
Iv'e read a lot of posts both in stackoverflow and other websites talking about web security. Such as salting encrypting etc. And I'm kinda not getting it so a simple explanation would be really helpful.
So here's what I know so far. A user logs in types his username and password. The input then goes through a process. Lets say the username and password is combined like for example:
$username = (USERS USERNAME INPUT);
$password = (USERS PASSWORD INPUT);
$userinput = $username . $password;
Then we add some salt.
$salt1 = "13$13aVc!kd";
$salt2 = "4kr$!vlmeoc";
$salted = $salt1 . $userinput . $salt2;
Then we encrypt it.
$encrypted = encrypt($salted);
Then check with the database and if its right user gets logged in.
That's how it works right? But Iv'e read about brute force attack. It guesses the input values right? With the procedure above. Doesn't it shows that the attacker only needs to get the $userinput information correct to get in? He doesn't need to guess the long $encrypted string correct?
Note: Lets say in this situation there's no captcha, no number of tries limit, no lockout, nothing else but the one above.
Note: Be gentle I'm still learning.
If you rule out captchas, try limits, lockouts, et cetera... then yes. You just have to brute force the plain text string.
However, that does take time - at the very least, it's bounded by the rate at which the server will respond to login requests. Even if the developer doesn't add any measures to prevent brute forcing, the server itself can only go through the encryption + verification process so quickly, and can only handle so many parallel requests.
That said, this is why it's important to
As a user, use a strong, hard to brute-force password
As a developer, have adequate measures to prevent brute-forcing of your login process
Hashing and salting passwords isn't to protect against people who brute force the natural login process (there are other things that protect against that). Instead, they're to protect against potential compromise of the password storage itself (e.g. someone dumping the contents of the database).
Both hashing and salting serve to decrease the speed at which someone with access to the stored passwords can retrieve the plain text string they'd need to be able to go through the natural login process (of your site or other sites, given that passwords are commonly shared between sites) without tripping anti-brute-forcing security measures.
The idea of hashing and salting is more to prevent someone from taking user passwords if the database itself is compromised. If the passwords are stored as salted and hashed strings, the attacker can't just use them to access a user's account on another site.
Password encryption is one-way encryption (or rather its suppose to be in a secure site). That is to say you take the password and you make a hash form it. bcrypt for example is the acceptable standard for doing this today.
If its one-way encryption a lot of people wonder how it can check a password. But you just hash the password the user submits and compare it to what hash you stored in the database. This way if your database is stolen an attacker has to work a lot harder.
The problem with just hashing a password is easily brute forced or rainbow tabled. You can google rainbow table to learn more on that. But essentially its a way to turn these hashes back into passwords.
Enter salting. Salting is adding random data essentially to every password. This trumps rainbow tables. Meaning a compromised database will mean brute force. Which if you're using a hash system like bcrypt takes a lot of time and effort for the attacked.
Having said all that. Best not to reinvent the wheel. Just use a known good authorization system if you can.
See my answer here
And you should generate unique salts for each entry when you create the hash.
One problem with brute force attacks is when you use a fast encryption like SHA1 or MD5. These functions are build to run the password through an algorithm fast. Instead you could use the Blowfish method, which im no expert on, but long story short it takes more calculation for a returned value, than SHA1 or MD5. This means it may take 5 years to brute force a password, hashed with Blowfish because of calculation time.
The next example is made with SHA1 and MD5, so it's vulnerable to bruteforce attacks, however the salt part should be OK to use:
$salt = md5(microtime().uniqueid());
This will output a unique 32 charecter salt, which you will put together with the password.
$passwod = $_POST['password'];
$hashed_password = sha1($password.$salt);
Now you have to store both the password and the salt in the database. And when you check the user inputtet password you get the salt, and hash the whole thing.
$temp_pass = $_POST['temp_pass'];
$salt = //from database;
$database_pass = //hashed pass from database;
$hashed_temp_pass = sha1($temp_pass.$salt);
if(hashed_temp_pass == $database_pass){
//Welcome user!
}
else{
//go away
}

Salt and passwords [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Secure hash and salt for PHP passwords
WARNING Don't use MD5 for passwords, use an alternative like bcrypt
For my passwords should I use salt like this (the salt will be unique to each user and not stored directly with the password)...
$salt = sha1(md5("coders gonna code"));
$password = md5($salt.$password);
or would it be okay if I just used:
$password = md5($password);
because if I used salt, even if the user makes up a bad password like password it won't matter because the salt (in this case) would be 145ac26ff093c6e1317f7d5fb4c9fd11c77be975 so the entry for there password would be 145ac26ff093c6e1317f7d5fb4c9fd11c77be975password which according to http://howsecureismypassword.net/ it would take 3 octodecillion years to crack.... so opinions? Or should I be even worse and go
$password = md5($salt.$password.md5($salt));
If the person has gone far enough to get the salt hash, would anything be able to stop then going futher? < More of a statement this last password
To everyone who said I should do it per user... I know, this is just an example.
You should change the salt so that it is specific to each user, not a system wide constant. This will make rainbow table attacks against your password hashes much more inconvenient.
There is a good write up on the evolution of salting in this article by Troy Hunt.
Edit
$salt something unique to each password record, which adds much entropy to it. This is usually a random sequence of bytes, stored with the user account.
Hashing is traditionally done on the concatenation of salt + password.
$passwordHash = hash($salt.$password);
As others have said, don't use MD5 for hashing. It is broken.
Applying additional proprietary algorithms to password or salt prior to hashing is not recommended. Instead, look at an industry strength solution such as PBKDF2, which, in addition to salting, also requires many (typically > 10k) repeated iterations which will further slow down an attacker.
If you adopt OWASP guidelines, the number of hashes performed should be increased regularly (to counteract Moore's Law). The number of hashes should also be persisted per user, meaning you will need to store the triple of hashed password, salt, and number of iterations.
You are using the salt totally incorrectly. Salts should be unpredictable; your salt is the exact opposite of that (fixed). Since a fixed hash is of absolutely no benefit, it also seems that you are counting on the salt not being known by the attacker. This is the definition of security through obscurity, which is another bad practice.
What you should be doing is:
Use an unpredictable string of reasonable length as the salt. Randomly generated 8-character strings from a pool such as lower/upper case letters and digits are fine.
Use a different salt for each user, and change it every time they change their password.
Move from MD5 (which is considered broken) to another hash function better suited to this application. SHA-1 is better because it's not considered broken; bcrypt is the best because it has a configurable load factor.
Don't use MD5 as your hashing algorithm, use something more secure such as SHA256 or even bcrypt.
Definately salt the password, if someone did gain entry to your database they would not be able to reverse the passwords for common hashes or using techniques such as rainbow attacks.
http://michaelwright.me/php-password-storage
http://en.wikipedia.org/wiki/Bcrypt
First of all you should never store md5 directly, which you regognized already.
PHP 5.5 will bring new methods to easily create and verify passwords in 1 line, until then you can use https://github.com/ircmaxell/password_compat (forward-compatible) to generate & verify safe password hashes.
I think salt is understood here incorrectly. The idea of salt is that it should be unique per hash. The reason is that when you create hash some different strings may have the same hash.
In your example you're hashing password too so it won't look like: 145ac26ff093c6e1317f7d5fb4c9fd11c77be975password
P.S. Use bcrypt. It's much more reliable.
Salts are meant to be completely random, and unrelated to the actual password you are storing a hash of.
What you should really do is generate a completely random salt, then do
$password = md5($salt.$password);
and store the user's username, salt and hashed password.

Categories