Jump to content

Hi!

So I'm creating a website and I really don't get the usage of hashes. So, php encrypts the password, ok, and I can decrypt it in another page if I choose to get it off my database there for some sort of usage. But what good does it do if someone picks up the password? Couldn't they just make a php script to decrypt it on their local system? What stops it from being as useless as saving it as plain text? Sure the intruder could just go ahead and login as another user faster, but a "insert password here" page on local-host wouldn't make it more than a few seconds slower.

Thanks in advance.

Link to comment
https://linustechtips.com/topic/528525-php-password_hash-how-does-it-work/
Share on other sites

Link to post
Share on other sites

if you're able to DECRYPT a password, you're doing it WRONG.

 

You hash a password client-side (a hash is only 1-way, you can go PW => hash, not hash=>pw) and you compare the hash to the one store in your DB.

 

I suggest you read up on this if you're actually thinking of making a website and putting it into production. Take a good look at injections and cross site scripting as well. On YouTube, you should look up Tom Scott, he has some very interesting videos about security.

 

This one's also good:

"It's a taxi, it has a FARE METER."

Link to post
Share on other sites

Hi!

So I'm creating a website and I really don't get the usage of hashes. So, php encrypts the password, ok, and I can decrypt it in another page if I choose to get it off my database there for some sort of usage. But what good does it do if someone picks up the password? Couldn't they just make a php script to decrypt it on their local system? What stops it from being as useless as saving it as plain text? Sure the intruder could just go ahead and login as another user faster, but a "insert password here" page on local-host wouldn't make it more than a few seconds slower.

Thanks in advance.

 

A hash cannot be decrypted. A hash is an algorithm used for one-way encryption, meaning it cannot be encrypted. Passwords are supposed to be stored hashed, meaning, they go through the one-way encryption so they cannot be decrypted (without some beefy computing power and a big understanding of the maths behind hashing, which isn't easy by any means).

 

Popular hashes include SHA-1 and MD5. Do not use MD5 for password hashing.

 

When a user enters a password, it is hashed, meaning that "PasswordPassword123" will look something like "hjbveuirt7834vnh8347vn347hg784vhytg" when hashed. Changing one letter in the password will result in a completely different hash, but if "PasswordPassword123" will always result in "hjbveuirt7834vnh8347vn347hg784vhytg" when hashed.

 

If the user goes to log in to the system, the password is hashed, and if that hash matches the hash in the database, then the password is correct. You can read more on the official PHP documentation on how php_password works. Here are a list of hashing functions you should avoid: https://en.wikipedia.org/wiki/Category:Broken_hash_functions

Speedtests

WiFi - 7ms, 22Mb down, 10Mb up

Ethernet - 6ms, 47.5Mb down, 9.7Mb up

 

Rigs

Spoiler

 Type            Desktop

 OS              Windows 10 Pro

 CPU             i5-4430S

 RAM             8GB CORSAIR XMS3 (2x4gb)

 Cooler          LC Power LC-CC-97 65W

 Motherboard     ASUS H81M-PLUS

 GPU             GeForce GTX 1060

 Storage         120GB Sandisk SSD (boot), 750GB Seagate 2.5" (storage), 500GB Seagate 2.5" SSHD (cache)

 

Spoiler

Type            Server

OS              Ubuntu 14.04 LTS

CPU             Core 2 Duo E6320

RAM             2GB Non-ECC

Motherboard     ASUS P5VD2-MX SE

Storage         RAID 1: 250GB WD Blue and Seagate Barracuda

Uses            Webserver, NAS, Mediaserver, Database Server

 

Quotes of Fame

On 8/27/2015 at 10:09 AM, Drixen said:

Linus is light years ahead a lot of other YouTubers, he isn't just an average YouTuber.. he's legitimately, legit.

On 10/11/2015 at 11:36 AM, Geralt said:

When something is worth doing, it's worth overdoing.

On 6/22/2016 at 10:05 AM, trag1c said:

It's completely blown out of proportion. Also if you're the least bit worried about data gathering then you should go live in a cave a 1000Km from the nearest establishment simply because every device and every entity gathers information these days. In the current era privacy is just fallacy and nothing more.

 

Link to post
Share on other sites

A hash cannot be decrypted. A hash is an algorithm used for one-way encryption, meaning it cannot be encrypted. Passwords are supposed to be stored hashed, meaning, they go through the one-way encryption so they cannot be decrypted (without some beefy computing power and a big understanding of the maths behind hashing, which isn't easy by any means).

 

Popular hashes include SHA-1 and MD5. Do not use MD5 for password hashing.

 

When a user enters a password, it is hashed, meaning that "PasswordPassword123" will look something like "hjbveuirt7834vnh8347vn347hg784vhytg" when hashed. Changing one letter in the password will result in a completely different hash, but if "PasswordPassword123" will always result in "hjbveuirt7834vnh8347vn347hg784vhytg" when hashed.

 

If the user goes to log in to the system, the password is hashed, and if that hash matches the hash in the database, then the password is correct. You can read more on the official PHP documentation on how php_password works. Here are a list of hashing functions you should avoid: https://en.wikipedia.org/wiki/Category:Broken_hash_functions

I'm probably not completely sure of what I am talking about here, but I read those types of passwords that always stay the same are easy to figure out as there are huge lists of pre-hashed words, making them easy to figure out.

Link to post
Share on other sites

The output from password_hash can't be converted back to plain text - the only way to verify that someone has entered the correct password is to hash the password that they have entered, and see whether it matches. The only way to obtain the plain text from the hash is to brute force attack the password, but as long as the password is fairly strong, that takes far, far too long to be feasible (like at least hundreds of years if you have a completely random, reasonable length password).

 

The disadvantage with hashing is that in theory, a different password can result in the same hash, but the probability of that happening in a cryptographically secure hash function (such as bcrypt, which password_hash uses) is incredibly low the hash is 184 bits long, which means that there are 2.5 * 10^55 different hashes that can be produced.

 

The PHP function increases security further by generating a salt, which is just a short random string per user that is hashed with the password, so that someone can't compute all the possible hashes before hand, then, every time they hack a site, just look at the list of precomputed hashes to see if any of them match.

HTTP/2 203

Link to post
Share on other sites

if you're able to DECRYPT a password, you're doing it WRONG.

 

You hash a password client-side (a hash is only 1-way, you can go PW => hash, not hash=>pw) and you compare the hash to the one store in your DB.

 

I suggest you read up on this if you're actually thinking of making a website and putting it into production. Take a good look at injections and cross site scripting as well. On YouTube, you should look up Tom Scott, he has some very interesting videos about security.

 

This one's also good:

Oh, ok, so you're comparing hashed passwords with hashed passwords, but what about the types of hashing that change every time, the ones that have a salt inside themselves?

And thanks a lot for the resources.

Link to post
Share on other sites

Oh, ok, so you're comparing hashed passwords with hashed passwords, but what about the types of hashing that change every time, the ones that have a salt inside themselves?

And thanks a lot for the resources.

The salt is stored along site the hash, so you just reuse the same salt each time you verify it (if you use the built in password_verify function, it will do that for you). It doesn't matter if the salt is public knowledge, because its purpose is to prevent someone brute forcing everyone's password at once (which would sort of be the Birthday Paradox), not to prevent a targeted brute force attack (though, if you were able to separate them so that if you have the password hashes, you still don't have the salts, it would work for that. The problem is that it's impractical to do that, because you need a different salt for each user, and storing it in the DB would defeat the point).

HTTP/2 203

Link to post
Share on other sites

The output from password_hash can't be converted back to plain text - the only way to verify that someone has entered the correct password is to hash the password that they have entered, and see whether it matches. The only way to obtain the plain text from the hash is to brute force attack the password, but as long as the password is fairly strong, that takes far, far too long to be feasible (like at least hundreds of years if you have a completely random, reasonable length password).

 

The disadvantage with hashing is that in theory, a different password can result in the same hash, but the probability of that happening in a cryptographically secure hash function (such as bcrypt, which password_hash uses) is incredibly low the hash is 184 bits long, which means that there are 2.5 * 10^55 different hashes that can be produced.

 

The PHP function increases security further by generating a salt, which is just a short random string per user that is hashed with the password, so that someone can't compute all the possible hashes before hand, then, every time they hack a site, just look at the list of precomputed hashes to see if any of them match.

Ohh! Ok! The other thing I don't get is on what side things are executed, like, if I login and enter my password into a page with a form that uses POST, and then goes to the page where it hashes the password in the $_POST and sends it to the database, how is that being done client-side if I'm able to login into my database with the server name being localhost in that same page? Is it just a function thing?

And also, I've read post is highly unsafe, along with get, so is there a way of encrypting the password from the form while still in the same page, so that it can't be picked up between pages(I think that's how the passwords could get obtained)?

And even then what is SSL so famous for if the password already travels hashed and any packet sniffer that could get his hands on it can't crack it in hundreds of years?

Link to post
Share on other sites

Ohh! Ok! The other thing I don't get is on what side things are executed, like, if I login and enter my password into a page with a form that uses POST, and then goes to the page where it hashes the password in the $_POST and sends it to the database, how is that being done client-side if I'm able to login into my database with the server name being localhost in that same page? Is it just a function thing?

And also, I've read post is highly unsafe, along with get, so is there a way of encrypting the password from the form while still in the same page, so that it can't be picked up between pages?

I'm not quite sure what you mean in your first paragraph. Do you mean that you're able to log in without actually loading a new page - it just loads inline? If so, there's some javascript on the page that is making the post request in the background without reloading the page, then making the appropriate changes in your browser and loading the new data.

 

All HTTP requests are unsafe if someone is able to perform a Man-In-The-Middle (MitM) attack on you, which means that they are reading all of the traffic between you and the server. The only actual solution to this is to use HTTPS (you can get free HTTPS certificates from LetsEncrypt and StartSSL). Hashing the password client side sounds like a sensible solution at first, but the problem with that approach is that all you've done is change the actual proof of identity from the password to the hash. If someone performs a MitM attack on you, and steals the password hash that you are now sending, they are still able to log in as you, though they wouldn't be able to use the login form on your site (they would just emulate the HTTP request that the form would make, then take the authentication token that you provide (probably the cookie) and add it to their browser, then they are logged in as you).

HTTP/2 203

Link to post
Share on other sites

Ohh! Ok! The other thing I don't get is on what side things are executed, like, if I login and enter my password into a page with a form that uses POST, and then goes to the page where it hashes the password in the $_POST and sends it to the database, how is that being done client-side if I'm able to login into my database with the server name being localhost in that same page? Is it just a function thing?

And also, I've read post is highly unsafe, along with get, so is there a way of encrypting the password from the form while still in the same page, so that it can't be picked up between pages(I think that's how the passwords could get obtained)?

And even then what is SSL so famous for if the password already travels hashed and any packet sniffer that could get his hands on it can't crack it in hundreds of years?

 

SSL(TLS) encrypts the entire page while its in transit, hence the name 'Transport Layer Security'. This includes any HTML and headers (form submissions and the webpage URI after the domain name).

 

PHP code itself is executed on your server, and it only sends the resulting HTML to the webpage. For example if you had something like this in PHP

<?php echo "<title>Hello World</title>"; ?>

Only this would get sent to the browser

<title>Hello World</title>

because the server would have already processed the PHP code. Your client's browser does not see any PHP that you have, unless the webpage extenion is .html instead of .php, which would mean PHP code hasn't been processed by your server.

Speedtests

WiFi - 7ms, 22Mb down, 10Mb up

Ethernet - 6ms, 47.5Mb down, 9.7Mb up

 

Rigs

Spoiler

 Type            Desktop

 OS              Windows 10 Pro

 CPU             i5-4430S

 RAM             8GB CORSAIR XMS3 (2x4gb)

 Cooler          LC Power LC-CC-97 65W

 Motherboard     ASUS H81M-PLUS

 GPU             GeForce GTX 1060

 Storage         120GB Sandisk SSD (boot), 750GB Seagate 2.5" (storage), 500GB Seagate 2.5" SSHD (cache)

 

Spoiler

Type            Server

OS              Ubuntu 14.04 LTS

CPU             Core 2 Duo E6320

RAM             2GB Non-ECC

Motherboard     ASUS P5VD2-MX SE

Storage         RAID 1: 250GB WD Blue and Seagate Barracuda

Uses            Webserver, NAS, Mediaserver, Database Server

 

Quotes of Fame

On 8/27/2015 at 10:09 AM, Drixen said:

Linus is light years ahead a lot of other YouTubers, he isn't just an average YouTuber.. he's legitimately, legit.

On 10/11/2015 at 11:36 AM, Geralt said:

When something is worth doing, it's worth overdoing.

On 6/22/2016 at 10:05 AM, trag1c said:

It's completely blown out of proportion. Also if you're the least bit worried about data gathering then you should go live in a cave a 1000Km from the nearest establishment simply because every device and every entity gathers information these days. In the current era privacy is just fallacy and nothing more.

 

Link to post
Share on other sites

And even then what is SSL so famous for if the password already travels hashed and any packet sniffer that could get his hands on it can't crack it in hundreds of years?

In theory, yes. However, the current industry standard encryption method, AES, in it's weakest configuration (AES 128), would take about one billion, billion years to brute force crack, if you're using a supercomputer. I think you'll probably have changed your password by then.

HTTP/2 203

Link to post
Share on other sites

SSL(TLS) encrypts the entire page while its in transit, hence the name 'Transport Layer Security'. This includes any HTML and headers (form submissions and the webpage URI after the domain name).

 

PHP code itself is executed on your server, and it only sends the resulting HTML to the webpage. For example if you had something like this in PHP

<?php echo "<title>Hello World</title>"; ?>

Only this would get sent to the browser

<title>Hello World</title>

because the server would have already processed the PHP code. Your client's browser does not see any PHP that you have, unless the webpage extenion is .html instead of .php, which would mean PHP code hasn't been processed by your server.

But doesn't that defeat the purpose of hashing a bit? If what you're telling me is right then when a user submits a form, the raw text will just fly around the internet to the server, where it is hashed and saved, and if that is the case a MitM attack that could see all the traffic of the server would know all the passwords being entered, and the only thing hashing would prevent would be damage done in case anyone could actually go into the database and see the raw text.

Link to post
Share on other sites

But doesn't that defeat the purpose of hashing a bit? If what you're telling me is right then when a user submits a form, the raw text will just fly around the internet to the server, where it is hashed and saved, and if that is the case a MitM attack that could see all the traffic of the server would know all the passwords being entered, and the only thing hashing would prevent would be damage done in case anyone could actually go into the database and see the raw text.

 

SSL(TLS) encrypts all the transported data, including form submissions, as these are a part of the headers.

Speedtests

WiFi - 7ms, 22Mb down, 10Mb up

Ethernet - 6ms, 47.5Mb down, 9.7Mb up

 

Rigs

Spoiler

 Type            Desktop

 OS              Windows 10 Pro

 CPU             i5-4430S

 RAM             8GB CORSAIR XMS3 (2x4gb)

 Cooler          LC Power LC-CC-97 65W

 Motherboard     ASUS H81M-PLUS

 GPU             GeForce GTX 1060

 Storage         120GB Sandisk SSD (boot), 750GB Seagate 2.5" (storage), 500GB Seagate 2.5" SSHD (cache)

 

Spoiler

Type            Server

OS              Ubuntu 14.04 LTS

CPU             Core 2 Duo E6320

RAM             2GB Non-ECC

Motherboard     ASUS P5VD2-MX SE

Storage         RAID 1: 250GB WD Blue and Seagate Barracuda

Uses            Webserver, NAS, Mediaserver, Database Server

 

Quotes of Fame

On 8/27/2015 at 10:09 AM, Drixen said:

Linus is light years ahead a lot of other YouTubers, he isn't just an average YouTuber.. he's legitimately, legit.

On 10/11/2015 at 11:36 AM, Geralt said:

When something is worth doing, it's worth overdoing.

On 6/22/2016 at 10:05 AM, trag1c said:

It's completely blown out of proportion. Also if you're the least bit worried about data gathering then you should go live in a cave a 1000Km from the nearest establishment simply because every device and every entity gathers information these days. In the current era privacy is just fallacy and nothing more.

 

Link to post
Share on other sites

SSL(TLS) encrypts all the transported data, including form submissions, as these are a part of the headers.

So SSL is basically monopolizing most of the internet's security just like that? Why can't I make "my own SSL" in case I'm a control freak? I mean I guess being a control freak only happens to a certain extent but is it doable? How does it actually work in the first place? Does it see what you are sending and just makes it make a stop at the encrypt-drive to then proceed encrypted to the de-crypt-drive on the other end of the internet road?

 

Also is there any alternative to forms that would hash the data client-side? I wouldn't mind having everything delivered already hashed, more server resources for me :D

I guess it'd make me kind of a dick but it's barely noticeable and it only matters when logging in / registering.

Link to post
Share on other sites

In theory, yes. However, the current industry standard encryption method, AES, in it's weakest configuration (AES 128), would take about one billion, billion years to brute force crack, if you're using a supercomputer. I think you'll probably have changed your password by then.

I love the way you love your numbers :D

Wouldn't it be a lot faster if the MitM used some sort of ASCI hardware like for mining bitcoin?

Link to post
Share on other sites

I love the way you love your numbers :D

Wouldn't it be a lot faster if the MitM used some sort of ASCI hardware like for mining bitcoin?

Actually, all relatively recent processors (well, x86-64 processors from the past 6 years, so all Intel and AMD ones in that time) support the AES instruction set, which essentially means that AES is hardware accelerated even on conventional hardware. But no matter what hardware you have, there's no way that you're going to be able to reduce that billion billion years (that's 1018 years, the universe is only 1.36 * 1010 years old) to anything remotely plausible.

 

So SSL is basically monopolizing most of the internet's security just like that? Why can't I make "my own SSL" in case I'm a control freak? I mean I guess being a control freak only happens to a certain extent but is it doable? How does it actually work in the first place? Does it see what you are sending and just makes it make a stop at the encrypt-drive to then proceed encrypted to the de-crypt-drive on the other end of the internet road?

 

Also is there any alternative to forms that would hash the data client-side? I wouldn't mind having everything delivered already hashed, more server resources for me :D

I guess it'd make me kind of a dick but it's barely noticeable and it only matters when logging in / registering.

SSL (actually TLS, which has replaced SSL) is a protocol that allows you to use any encryption method you like, as long as both parties support it. TLS just provides the mechanism for deciding which encryption method to use, as well as a way of securely deciding on an encryption key to use. The exact way that it works is too complicated for me to explain here, but you can get a good idea for how it works from the top three answers on this security.stackexchange question.

If you're interested in learning about how the actual encryption works, the AES wikipedia page goes quite in depth. If you're not looking for something as technical, it basically just splits the message up into chunks, each of length 128 bits (16 bytes/characters), then the block that is being worked on is combined with the result of the previous block, each byte of the result is replaced with a different one based on a table of input=>output, then some of the bytes are shuffled around.

 

In theory, you could write your own encryption algorithm. However, I cannot stress enough that doing so for the purpose of security is a terrible idea (the only time that it makes sense is as an educational exercise) - many people have tried to break AES, as well as TLS and the encryption elements used within it (specifically elliptic curve encryption and RSA), but they are still absolutely secure (though some weaknesses have been found, which are either not possible to exploit (there's an AES weakness that would reduce the time taken from a billion billion years to several hundred million billion years, as long as you have more ram in your computer than there is storage in every computer on the internet combined. If you made an encryption algorithm yourself, I guarantee that there would be some weakness that would make it easy to break.

 

As I said a couple of posts ago, hashing the data in the user's browser rather than on the server would open it up to a major security flaw

[...] Hashing the password client side sounds like a sensible solution at first, but the problem with that approach is that all you've done is change the actual proof of identity from the password to the hash. If someone performs a MitM attack on you, and steals the password hash that you are now sending, they are still able to log in as you, though they wouldn't be able to use the login form on your site (they would just emulate the HTTP request that the form would make, then take the authentication token that you provide (probably the cookie) and add it to their browser, then they are logged in as you).

HTTP/2 203

Link to post
Share on other sites

Actually, all relatively recent processors (well, x86-64 processors from the past 6 years, so all Intel and AMD ones in that time) support the AES instruction set, which essentially means that AES is hardware accelerated even on conventional hardware. But no matter what hardware you have, there's no way that you're going to be able to reduce that billion billion years (that's 1018 years, the universe is only 1.36 * 1010 years old) to anything remotely plausible.

 

SSL (actually TLS, which has replaced SSL) is a protocol that allows you to use any encryption method you like, as long as both parties support it. TLS just provides the mechanism for deciding which encryption method to use, as well as a way of securely deciding on an encryption key to use. The exact way that it works is too complicated for me to explain here, but you can get a good idea for how it works from the top three answers on this security.stackexchange question.

If you're interested in learning about how the actual encryption works, the AES wikipedia page goes quite in depth. If you're not looking for something as technical, it basically just splits the message up into chunks, each of length 128 bits (16 bytes/characters), then the block that is being worked on is combined with the result of the previous block, each byte of the result is replaced with a different one based on a table of input=>output, then some of the bytes are shuffled around.

 

In theory, you could write your own encryption algorithm. However, I cannot stress enough that doing so for the purpose of security is a terrible idea (the only time that it makes sense is as an educational exercise) - many people have tried to break AES, as well as TLS and the encryption elements used within it (specifically elliptic curve encryption and RSA), but they are still absolutely secure (though some weaknesses have been found, which are either not possible to exploit (there's an AES weakness that would reduce the time taken from a billion billion years to several hundred million billion years, as long as you have more ram in your computer than there is storage in every computer on the internet combined. If you made an encryption algorithm yourself, I guarantee that there would be some weakness that would make it easy to break.

 

As I said a couple of posts ago, hashing the data in the user's browser rather than on the server would open it up to a major security flaw

Thanks a lot man! You were really helpful! By the way, slightly non related question, escaping and then hashing the post(probably not hashing the whole post) before putting it in the database would prevent both injection and Cross Site Scripting, and if I use some sort of one time token to make sure that xyz form is coming from that one user and not some guy forging a request would pretty much make the website safe except for MitM attacks(and invading the actual server) right? It wouldn't I'm pretty sure, so what other attacks like these could be preformed that I can protect myself from? I'll probably get google and steam logins in the end but just for learning purposes :)

 

Also, if I set a salt the same way I'd set a token to get protection from request forging, wouldn't it make it so that it'd be at least a bit safer to hash something client side? Then I'd set another salt as it arrived on the server, effectively making the first one useless, so even if a MitM attack was to be preformed, by the time the attacker had emulated his form, that salt, and therefore that password, would already mean nothing to the server. Why not even use the token as the salt!

Link to post
Share on other sites

Thanks a lot man! You were really helpful! By the way, slightly non related question, escaping and then hashing the post(probably not hashing the whole post) before putting it in the database would prevent both injection and Cross Site Scripting, and if I use some sort of one time token to make sure that xyz form is coming from that one user and not some guy forging a request would pretty much make the website safe except for MitM attacks(and invading the actual server) right? It wouldn't I'm pretty sure, so what other attacks like these could be preformed that I can protect myself from? I'll probably get google and steam logins in the end but just for learning purposes :)

The password should be hashed, but there's no point escaping it first - the hash function takes raw binary data and outputs the hash, so no matter what the user enters, it should be safe to store (though you should never display the hash to the user because that would defeat the point of storing it securely).

The rest of the data, such as usernames, emails, etc, should be escaped (using htmlspecialchars($string, ENT_HTML5|ENT_QUOTES)) at some point. However, escaping them before storing in the database isn't always the best way to do it - what if you have to send the data in a plain text email, or as JSON encoded data? You obviously need to escape it at some point, but you may decide that it makes more sense to encode when displaying it rather than when storing it. That does allow more places for you to forget and therefore open up XSS (Cross-Site Scripting) vulnerabilities though, so do be careful.

You also need to make sure that you take the necessary precautions when inserting the data into the SQL database, to prevent SQL injection. The solution to this can be escaping (using mysqli_real_escape_string($string)), but I would strongly advise that you use prepared statements instead, either using mysqli or PDO (never, ever use the mysql class (rather than mysqli) - it is insecure and deprecated).

 

People forging requests is called Cross-Site Request Forgery (CSRF), and it's mitigated by generating a random token which you add as a hidden field in your form, and also storing somewhere associated with that user such as their $_SESSION or in a cookie. It is not recommended that you store the CSRF token in the database, because that would imply that it's a permanent token, so as soon as someone manages to steal it once, they can now forge requests forever. It doesn't make much sense for a login form, but it's important for a lot of forms. For example, on this site, if there wasn't any CSRF protection on the reply forms, someone could make a link that, when you click it, would make you post in a thread.

 

Also, if I set a salt the same way I'd set a token to get protection from request forging, wouldn't it make it so that it'd be at least a bit safer to hash something client side? Then I'd set another salt as it arrived on the server, effectively making the first one useless, so even if a MitM attack was to be preformed, by the time the attacker had emulated his form, that salt, and therefore that password, would already mean nothing to the server. Why not even use the token as the salt!

If you're using a random salt on the client side, then you would have to change it frequently for it to actually change your security in any way. The problem is, then the hash that you have on the server won't match because you are changing the data that you are hashing, and hashes are designed so that any change that you make should change, on average 50% of the bits of the data, so there's no way for you to tell whether their password was correct (you MUST NOT store the original password so that you can then hash that with the new salt).

HTTP/2 203

Link to post
Share on other sites

1. Store only hashed shit in the database, but one-way hashed.
2. Dont be and idiot and use prepared PDO, not mysqli -> https://www.owasp.org/index.php/SQL_Injection

3. Use SSL

4. Make the password hashing as slow as possible. 

5. Add salt. 

 

E4MUm3R.png

 

6. Read this -> http://php.net/manual/en/faq.passwords.php

 

And you are set.

 

Lenovo/IBM ThinkPad T61 Widescreen 15.4" 1680x1050
Intel Core2Duo T8300 2.4GHz | 3GB DDR2 from Hynix | SATA II Patched bios (Middleton) | Samsung EVO 850
Arch Linux | Linux 4.3.X x86_64

Link to post
Share on other sites

You hash a password client-side (a hash is only 1-way, you can go PW => hash, not hash=>pw) and you compare the hash to the one store in your DB.

Clarification on this; You do not hash the password client-side, hashing is always done server side. 

 

Popular hashes include SHA-1 and MD5. Do not use MD5 for password hashing.

Even SHA-1 is bad to use with passwords because of the low cost associated with generating a hash. Standards like Bcrypt and Scrypt are way better for storing passwords.

 

EDIT: thought I'd add some real code that I use in production for doing exactly this. (sorry, might look a little complex, it's using a class for the users and magic methods to set and get the values)

USER.PHPClass Users {        public function __set($name, $value) {		if ($name == "password") {			$value = password_hash($value, PASSWORD_DEFAULT);		} else {			$value = htmlspecialchars($value);		}		$query = "UPDATE users SET $name = :value WHERE id = :id";		$query_params = array(':id' => $this->userData['id'], ':value' => $value);		executeSQL($query, $query_params);	}}EXAMPLE CALL$user = new Users()$user->password = "ThisIsTheNewPasswordToBeSet";LOGIN.PHP if (password_verify($_POST['password'], $user->password)) {	$login_ok = true;}
Edited by Blade of Grass

15" MBP TB

AMD 5800X | Gigabyte Aorus Master | EVGA 2060 KO Ultra | Define 7 || Blade Server: Intel 3570k | GD65 | Corsair C70 | 13TB

Link to post
Share on other sites


Clarification on this; You do not hash the password client-side, hashing is always done server side. 

 

Even SHA-1 is bad to use with passwords because of the low cost associated with generating a hash. Standards like Bcrypt and Scrypt are way better for storing passwords.

 

EDIT: thought I'd add some real code that I use in production for doing exactly this. (sorry, might look a little complex, it's using a class for the users and magic methods to set and get the values)

USER.PHPClass Users {        public function __set($name, $value) {		if ($name == "password") {			$value = password_hash($value, PASSWORD_DEFAULT);		} else {			$value = htmlspecialchars($value);		}		$query = "UPDATE users SET $name = :value WHERE id = :id";		$query_params = array(':id' => $this->userData['id'], ':value' => $value);		executeSQL($query, $query_params);	}}EXAMPLE CALL$user = new Users()$user->password = "ThisIsTheNewPasswordToBeSet";LOGIN.PHP if (password_verify($_POST['password'], $user->password)) {	$login_ok = true;}

The way I'm doing it right now is just, when the user creates an account, it recieves a post with the password, htmlspecialchars's it, hashes it with bcrypt, uploads it onto the DB, then, on the login, it receives the post, htmlspecialchars, and password_verify's it against the hashed version in the db. Seems to be working quite flawlessly so far.

I'm gonna go through the manuals so I can understand your code. I don't understand classes too well I haven't had the need to get to it yet. Why would you need $name there? 

Why not just do UPDATE users SET password_column = etc

Link to post
Share on other sites

if you're able to DECRYPT a password, you're doing it WRONG.

 

You hash a password client-side (a hash is only 1-way, you can go PW => hash, not hash=>pw) and you compare the hash to the one store in your DB.

 

I suggest you read up on this if you're actually thinking of making a website and putting it into production. Take a good look at injections and cross site scripting as well. On YouTube, you should look up Tom Scott, he has some very interesting videos about security.

 

This one's also good:

Tom Scott.

 

One of my favourite people. :D

Link to post
Share on other sites

The way I'm doing it right now is just, when the user creates an account, it recieves a post with the password, htmlspecialchars's it, hashes it with bcrypt, uploads it onto the DB, then, on the login, it receives the post, htmlspecialchars, and password_verify's it against the hashed version in the db. Seems to be working quite flawlessly so far.

I'm gonna go through the manuals so I can understand your code. I don't understand classes too well I haven't had the need to get to it yet. Why would you need $name there?

Why not just do UPDATE users SET password_column = etc

I would suggest against using htmlspecialcharacters on a User's password as it doesn't give you any benefit.

The reason why I have the $name in the field is because I'm using a PHP Magic method. So when I try to set the user's password using

$user->password = "NewPassword";
PHP will essentially rewrite it to

$user->__set("password", "NewPassword");
The benefit to doing it this way is I can change any field extremely easy.

$user->email = $newEmail;$user->name = $neeName;Etc
Those all work automatically without me needing to modify the class (as long as the name of the field I'm changing matche the name of the field in the database).

15" MBP TB

AMD 5800X | Gigabyte Aorus Master | EVGA 2060 KO Ultra | Define 7 || Blade Server: Intel 3570k | GD65 | Corsair C70 | 13TB

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×