I have a small problem. In fact, I have a string crypted with the PHP function crypt(), with only one parameter (without the salt parameter).
I would like to know if it is possible to decrypt the password if it was crypted that way?
Thank you in advance!
No, this is impossible, because simply crypt() is a One-way string hashing.
You can, however, use brute force but it will be too bad if the password is lengthly...
Function crypt() uses a one-way algorithm, there is no decrypt function.
Well, crypt returns the digest of a hash algorithm which by design can't be reversed. Whether or not you posses the salt is irrelevant in this case.
You can try online Rainbow Tables like those at CrackStation to possibly look the hash up. Your only other alternative is to brute force the hash.
Related
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.
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
So far I have been using md5 to hash passwords on my site, no salt.
Now I am building an application that will have to be more secure and I'm reading md5 can be easily brute-force attacked.
So I want to use crypt() to hash the passwords.
What I have not fully understood is:
Do I have to provide a salt or is the built-in generated one ok?
How many times (if more than one) should I iterate the crypt function to be safe?
With md5, no matter the length of the input string, the hash was 32-digit. Does crypt return a standard length of hashes too?
You need to provide a salt, if you want to specify encryption other than DES. Otherwise, you're good with the default salt.
You don't iterate the crypt function yourself, this is done internally with algorithms where it makes sense. Number of iterations is specified via the salt.
Yes, the hash length of a given hash algorithm is standard; different hash algorithms have different hash lengths, however.
crypt can use different hash algorytms. With md5 it returns 128 bit integer (with 32 chars hex representation). Using crypt with a salt once is safe enought. It's recommended the salt to be provided by the application
An optional salt string to base the hashing on. If not provided, the
behaviour is defined by the algorithm implementation and can lead to
unexpected results.
For my website's password hashing I wrote the following function:
public function hash($user) {
$user_key = hash_hmac('sha512', $user['id'].$user['email'], $this->site_key);
$password = hash_hmac('sha512', $user['password'], $user_key);
}
I generate user unique keys to use for the final password hashing. Because this key is hashed with sha512 it should give enough security based on what I read on wikipedia:
The cryptographic strength of the HMAC depends upon the cryptographic strength of the underlying hash function, the size of its hash output length in bits and on the size and quality of the cryptographic key.
I have not seen this way if hashing passwords before and was wondering if it is good enough?
Extra: I have not used a salt because I think hmac appends the provided key to the data (like a salt), is this right?
OK, first and foremost. Do not write up your own function to do password hashing. I'm not doubting your skills, but to be safe do not do your own hashing system. And an HMAC your key is OK, but I'd still not use it.
Finally I'd suggest that you do this for your users passwords.
<?PHP
$password=$user['password'];
$username=$user['username'];
$salt='usesomesillystringforsalt';
$hashed_password=crypt($password.$username,'$2a$04$usesomesillstringforsalt$');
?>
This algorithm uses Bcrypt which is based upon Blowfish it is a very robust algorithm and is what Gawker media went to after they were hacked due to the robustness and usefulness for password hashing. crypt PHP Manual
Next up, remember to change the part that says usesomesillystringforsalt to something else. It needs to be 22 digits of base64 salt A-Z,a-z,0-9,/ and "."
Go to that link to find out more about the algorithm itself. I suggest that you just use this implementation as it is much much stronger than the one that you were suggesting.
If you want to go a step forward, I'd suggest that you use a unique salt for every user. If you want to do that, I can write up an example function which will show you how to do that.
As stated, if you have any more questions feel free to ask.
SQLite doesn't have MD5 built in, so I'm considering using the hash function instead. I don't know much about hashing, but I can see that hash() output is numerical and of varying length while MD5() returns mixed characteds/numbers of a fixed length.
I couldn't find anything on this on stackoverflow or google.
Can hash() with salt be used to safely store passwords?
EDIT: Super embarassing mistake, I actually ment hex(), not hash() - Sorry for the error
hex() is not a cryptographic function. All it does is return the hexadecimal value of the string you pass into it. This is not a secure way of storing passwords.
You want to create a hash value before storing the password in your SQLite database. Use the PHP hash() function as other answers have suggested.
You have this tagged as PHP as well, so why not use a PHP function to accomplish what you need? PHPass seems to be hot right now as people are moving away from sha1() and md5().
You can use hash to store passwords as long as you use seed, and use individual seed for every password. The hash function creates value which is unique for a unique string (you can hash other datatypes as well) so it is a good candidate for your task.
With the php hash function you can pass SHA256 to the first parameter and it will create a strong hash of the password + salt. There is no need for extra extensions, for a web application other than a high security system like a banking site, sha256 is fine. It may even be overkill.
hash('sha256',$salt . $password);
Should do the trick. Now you can save the data in a varchar column in your database since the hash function outputs a hex string. The hash function has variable output because it can use many different hashing algorithms. the hash function with sha256 as show above, will output 64 characters in a string. Putting the salt at the beginning is better than putting it at the end, as more randomness at the beginning of hashes is better than randomness at the end.
I couldn't find anything in the SQLite docs regarding a hash() function. You may be using SQLite with some basic third-party C/C++ plugins included, or you may be using the PHP hash() function (which allows you to specify the hashing algorithm to use).
Generally, a one-way hash is a good way to store passwords, and if it's the PHP hash, used with SHA256, I see no reason why it wouldn't work for you. Just be aware that some hashing functions have demonstrated flaws; MD5 can produce predictable and exploitable collisions, and SHA1 also has theoretical vulnerabilities. SHA2 algorithms including SHA256 are based on SHA1, but have not yet been shown to suffer the same weakness.
In any case, to help ensure a unique hash, use a hashing algorithm that produces a hash equal or larger than the message; it is trivial to prove that, given a finite set of hash values, there cannot be a unique hash value for each of the set of messages larger than the hash size.
Chances are you are using the PHP hash() function, which is more then functional. I would stay away from SHA1 and MD5, as they both have vulnerabilities or known reverse-lookup tables (IE, if someone got the hashed password, they could go to many sites available online and enter that in, and it will give them a password that will, when passed through MD5 or SHA1, give the same password.)
hash(256) or hash(512) are way more than what you could probably need, so those will probably be safe. Just remember to salt your passwords. You can never be too careful.