|
This is more a human horror than a coding horror, but this thread: http://news.ycombinator.com/item?id=4616704
|
# ? Oct 5, 2012 22:09 |
|
|
# ? May 17, 2024 01:28 |
|
shrughes posted:This is more a human horror than a coding horror, but this thread: http://news.ycombinator.com/item?id=4616704 I remember this story. It started a huge argument on a forum where it was me versus a guy who insisted that creating a perfect compressor (i.e. could compress and decompress every kind of file; he never caught on that if that were true, you could compress everything down to 1 byte), and it got so heated he was eventually banned. Did I mention this was an anarcho-capitalist forum? Strange times.
|
# ? Oct 5, 2012 22:27 |
|
I came across this particular gem while checking if is_numeric() had any stupid gotchas I needed to be aware of. php:<? // Released Under Affero General Public License, Version 3 (AGPL3) // Author: [email]holdoffhunger@gmail.com[/email] $result = "TRUE"; $testable_string = strtolower($string_to_test); $testable_string_length = strlen($string_to_test); for($i_string = 0; $i_string < $testable_string_length; $i_string++) { $current_value_to_test = $testable_string[$i_string]; if( ($current_value_to_test != "0") && ($current_value_to_test != "1") && ($current_value_to_test != "2") && ($current_value_to_test != "3") && ($current_value_to_test != "4") && ($current_value_to_test != "5") && ($current_value_to_test != "6") && ($current_value_to_test != "7") && ($current_value_to_test != "8") && ($current_value_to_test != "9") && ($current_value_to_test != "a") && ($current_value_to_test != "b") && ($current_value_to_test != "c") && ($current_value_to_test != "d") && ($current_value_to_test != "e") && ($current_value_to_test != "f") ) { $result = "FALSE"; $i_string = $testable_string_length; } } ?>
|
# ? Oct 6, 2012 01:41 |
|
People releasing really small snippets like that under non-public-domain licenses annoy the poo poo out of me.
|
# ? Oct 6, 2012 02:15 |
|
Zamujasa posted:I came across this particular gem while checking if is_numeric() had any stupid gotchas I needed to be aware of. Wow. I had to see if there was more from this person, and I wasn't disappointed, but now I wonder if it's a troll. http://www.php.net/manual/de/function.sort.php#104952 http://www.php.net/manual/it/function.filetype.php#108190 http://www.php.net/manual/it/imagick.getversion.php#108585 And my favorite: http://www.php.net/manual/it/function.unlink.php#104370 quote:There are two outcomes: (1) It deletes the file, and continues happily along, error message, or not. (2) It can't delete the file, can't modify the permissions, etc., and therefore, the script never completes, or it may throw some PHP errors at you eventually. Don't people cite all the community contributed code snippets in the PHP documentation as a point in the language's favor?
|
# ? Oct 6, 2012 02:21 |
|
A A 2 3 5 8 K posted:Wow. I had to see if there was more from this person, and I wasn't disappointed, but now I wonder if it's a troll.
|
# ? Oct 6, 2012 02:58 |
|
I want to thank everyone in this thread for giving me the push I needed to force all my applications to use encrypted passwords instead of plain text bullshit sitting in the database. I hated doing it that way from the start, but everyone insisted that they needed to be able to read the passwords in plain text so that they could provide them to users if they called in. At the time, it was easier to just do what the customers wanted and give them plain text passwords, but today I'd had enough. I decided gently caress them, I'm not being blamed for this poo poo getting compromised at some point and thousands of users passwords being out in the wild. Also, I've always been embarrassed to go back even a couple years and look at the crazy poo poo I wrote - now I'm looking at things as I write them and thinking "what the gently caress is wrong with you? There's a better way to do this." and I credit this thread for shaming me into being a better person. Thanks again everyone, I really appreciate it.
|
# ? Oct 6, 2012 06:36 |
|
GentlemansSleepover posted:I want to thank everyone in this thread for giving me the push I needed to force all my applications to use encrypted passwords instead of plain text bullshit sitting in the database. I hated doing it that way from the start, but everyone insisted that they needed to be able to read the passwords in plain text so that they could provide them to users if they called in. At the time, it was easier to just do what the customers wanted and give them plain text passwords, but today I'd had enough. I decided gently caress them, I'm not being blamed for this poo poo getting compromised at some point and thousands of users passwords being out in the wild. You're not supposed to store encrypted passwords, that is only a little better than storing them in plaintext. Use a one-way hash function.
|
# ? Oct 6, 2012 07:53 |
|
hieronymus posted:You're not supposed to store encrypted passwords, that is only a little better than storing them in plaintext. Use a one-way hash function. What one-way hash function would you recommend?
|
# ? Oct 6, 2012 07:55 |
|
shrughes posted:What one-way hash function would you recommend? perhaps i meant cryptographic when i said one way. SHA-256 hasn't been compromised, may as well go with that. Compute the hash based on the concatenation of salt (possibly time when password was entered + arbitrary string) + user password. That way no one knows the password and they can't plug your database into freerainbowtables.com.
|
# ? Oct 6, 2012 08:03 |
|
hieronymus posted:You're not supposed to store encrypted passwords, that is only a little better than storing them in plaintext. Use a one-way hash function.
|
# ? Oct 6, 2012 08:15 |
|
hieronymus posted:perhaps i meant cryptographic when i said one way. SHA-256 hasn't been compromised, may as well go with that. Compute the hash based on the concatenation of salt (possibly time when password was entered + arbitrary string) + user password. That way no one knows the password and they can't plug your database into freerainbowtables.com. No. Use something like bcrypt or scrypt that's designed to be slow to calculate, to slow down brute-force attacks.
|
# ? Oct 6, 2012 09:17 |
|
yaoi prophet posted:No. Use something like bcrypt or scrypt that's designed to be slow to calculate, to slow down brute-force attacks. Ugg, I googled this and found http://hashcat.net/oclhashcat-plus So yep, I am embarrassingly wrong about SHA-256.
|
# ? Oct 6, 2012 09:37 |
|
That is normal. Number one rule of security: You're always wrong, even when you're aware of this rule.
|
# ? Oct 6, 2012 14:48 |
|
we moved to bcrypt for one of our products and was surprised to learn that it truncates password characters after 72. That seems reasonable, but still, figured I would have heard of that by now.
|
# ? Oct 6, 2012 15:04 |
|
code:
|
# ? Oct 6, 2012 15:41 |
|
hieronymus posted:You're not supposed to store encrypted passwords, that is only a little better than storing them in plaintext. Use a one-way hash function. Sorry, wasn't clear about that, I did use a one-way hash. And now I'm not sure if the way I did it is the best possible solution, looking into new methods now.
|
# ? Oct 6, 2012 16:00 |
|
Lurchington posted:we moved to bcrypt for one of our products and was surprised to learn that it truncates password characters after 72. That seems reasonable, but still, figured I would have heard of that by now. I was unaware of this. But couldn't you MD5 the password and then bcrypt() it, and still gain all the benefits? edit: or would that leave you vulnerable to people generating collisions? I not clever at this cryptographic theory stuff. At any rate, pretend I asked: could you gain the benefits of bcrypt by applying it after applying an inexpensive hash function of your choice Hammerite fucked around with this message at 16:18 on Oct 6, 2012 |
# ? Oct 6, 2012 16:13 |
|
Hammerite posted:I was unaware of this. But couldn't you MD5 the password and then bcrypt() it, and still gain all the benefits? No, because that's just essentially like having a password policy which is "32 hex characters only" making them much easier to crack. Sure, you then have to crack the md5 hashes after that, but I'd imagine both steps together are easier than cracking a single completely unknown bcrypted password. e: having said that, I suspect that at 32 characters the differences you're talking about are orders of magnitudes of centuries or something Jonnty fucked around with this message at 16:22 on Oct 6, 2012 |
# ? Oct 6, 2012 16:20 |
|
hieronymus posted:SHA-256 hasn't been compromised, may as well go with that. hieronymus posted:So yep, I am embarrassingly wrong about SHA-256. That's because "compromised" doesn't mean poo poo for passwords. Cryptographic hashes are designed to make it difficult to intentionally create a different input that will result in the same output. If you can reasonably generate two inputs with the same output, then your hash has been compromised. This does not matter at all if you're trying to crack passwords.
|
# ? Oct 6, 2012 16:28 |
|
Hammerite posted:I was unaware of this. But couldn't you MD5 the password and then bcrypt() it, and still gain all the benefits? It's an interesting thought, but the only way I make sense of the whole cryptography thing is to assume that combining two of more types of hashing makes the whole thing worse than doing the "best" one. So I'm not sure.
|
# ? Oct 6, 2012 16:29 |
|
Actually, I suppose 36 characters (based on using UTF-16) isn't so bad as to require extra steps, so maybe it's not really that big a deal. You could even apply a rule like: work out how many characters of the password fit in 72 bytes when it is represented as UTF-8, and if it is less than 36, convert it to UTF-16 and use that instead... or does that have some kind of pitfall?
|
# ? Oct 6, 2012 16:35 |
|
It's like padding the key with zeros.
|
# ? Oct 6, 2012 16:45 |
|
Before hashing, you should also salt the password, against eg a username plus an arbitrary string. Here's a good article explaining what salting is good for (pg 3), and why bulk hash algorithms (md5/sha1/similar) aren't the best choice for encrypting passwords (pg4), among lots of other info. I recommend reading the whole thing. Repeat hashing is typically done against the same algorithm. Eg repeat a given hash algorithm a few thousand times instead of just once. I think bcrypt does this, for example. But I think this is mainly just performed in order to make it more computationally intensive to bruteforce; there's otherwise little effective increase in security. Hammerite posted:You could even apply a rule like: work out how many characters of the password fit in 72 bytes when it is represented as UTF-8, and if it is less than 36, convert it to UTF-16 and use that instead... or does that have some kind of pitfall?
|
# ? Oct 6, 2012 16:47 |
|
beoba posted:I don't think that would really help things. It doesn't increase the number of permutations that a cracker would need to iterate over; they could just do the same thing on their end when bruteforcing. If they have your encrypted passwords, it's not a stretch to assume that they also have your code. If you read my post, I am solely concerned with the restriction on bcrypt that the password must be at most 72 bytes in length. I was not proposing that idea as a way of improving the obscurity of the hashing scheme, nor am I proposing it as a way of improving the difficulty of breaking the hashing scheme, except in so far as if a user creates a password that is heavy on 3+ byte UTF-8 characters, you would be able to make use of a longer prefix of that password. edit: But I was forgetting about the salt. That restricts the size of passwords still further. It is quite peculiar that you don't hear much about this limitation of the bcrypt algorithm. Hammerite fucked around with this message at 17:03 on Oct 6, 2012 |
# ? Oct 6, 2012 16:59 |
|
Hammerite posted:It is quite peculiar that you don't hear much about this limitation of the bcrypt algorithm. Probably because is doesn't matter. If you pick a work factor so that each hash calculation takes about one second, and then you restrict your 72 character password to only numbers that are smaller than two, then we're still talking around 100 trillion years of CPU time to brute force your password.
|
# ? Oct 6, 2012 17:21 |
|
Zhentar posted:Probably because is doesn't matter. If you pick a work factor so that each hash calculation takes about one second, and then you restrict your 72 character password to only numbers that are smaller than two, then we're still talking around 100 trillion years of CPU time to brute force your password. Yeah, I had brought it up in the first place, but I still think it doesn't matter. It's just the kind of point that you'd normally expect to be flogged over and over in cryptography holy wars.
|
# ? Oct 6, 2012 18:13 |
|
bcrypt already salts and works. use bcrypt.
|
# ? Oct 6, 2012 19:06 |
|
Everyone on this page: Stop trying to implement your own encryption mechanisms and/or password storage mechanisms. Stop trying to improve on existing technologies, you're most likely not. Cryptography is like, legit, hard. Do not preprocess your passwords/plaintext in any way before inputting them to the library function.
|
# ? Oct 6, 2012 19:07 |
Wheany posted:Everyone on this page: Stop trying to implement your own encryption mechanisms and/or password storage mechanisms. Stop trying to improve on existing technologies, you're most likely not. Cryptography is like, legit, hard. A million times this. If you haven't studied cryptography for at least 10 years you are most certainly wrong. If you have, you probably still made a fault in your reasoning somewhere.
|
|
# ? Oct 6, 2012 19:39 |
|
Strong Sauce posted:bcrypt already salts and works. use bcrypt. Oh, I see that I was misunderstanding. the salt is obtained from the bcrypt implementation and does not count toward the 72-byte limit. Still though, I am curious. When you are asking a user to set a password, what is the best procedure to follow? Do you let them enter a long password and silently truncate it to 72 bytes? Do you enforce a limit on the length of the password? (I had thought that both of these were generally considered to be a bad thing to do.) If you do enforce a limit, what limit exactly? 72 bytes is 36 UTF-16 characters, or 24+ UTF-8 characters (but practically speaking passwords probably won't all be composed of 3-byte characters); but then again those numbers presuppose that you do not allow non-BMP characters...
|
# ? Oct 6, 2012 20:11 |
|
Hammerite posted:Do you enforce a limit on the length of the password? (I had thought that both of these were generally considered to be a bad thing to do.)
|
# ? Oct 6, 2012 20:18 |
|
Aleksei Vasiliev posted:Limiting password length is considered a bad thing when it's limited to like <20chars or so. My bank for a long time limited passwords to 8chars, which is awful. Limiting them to 72 bytes is really not an issue. But again, what limit do you impose? Option 1: You impose a limit of 72 bytes on the UTF-8 representation of the entered password. Problem: You reject some passwords in a seemingly (to the user) capricious fashion and can't specify a solid upper limit on password length. Option 2: You impose a limit of 18 characters (18 characters * 4 bytes/character = 72 bytes; non-BMP characters take up 4 bytes in both UTF-8 and UTF-16) Problem: That's quite a small limit. Option 3: You impose a limit of 36 characters and disallow non-BMP characters (and run bcrypt on the UTF-16 representation of the password). Problem: Not too bad, but it seems a little arbitrary to disallow non-BMP characters.
|
# ? Oct 6, 2012 20:23 |
|
Hammerite posted:Option 1: You impose a limit of 72 bytes on the UTF-8 representation of the entered password. It's this.
|
# ? Oct 6, 2012 21:10 |
|
For gently caress's sake, just md5 hash it before throwing it into bcrypt. There's nothing wrong with doing that.
|
# ? Oct 6, 2012 22:48 |
|
bcrypt hash it and throw it into md5
|
# ? Oct 6, 2012 22:58 |
|
shrughes posted:For gently caress's sake, just md5 hash it before throwing it into bcrypt. There's nothing wrong with doing that. Use SHA-512 and the raw binary results instead of hex digits, for 64 bytes of bcrypt goodness. Fakedit: Is there a good explanation of how to do this? I'm assuming that it's just using the Blowfish version of php's crypt() function, but if there's a better way and some examples I'm all ears to learning how to do passwords right.
|
# ? Oct 6, 2012 23:02 |
|
A lot of dudes just don't limit it and let bcrypt or whatever truncate the password, since by the time you're entering 72 byte passwords you're getting more out of the convenience of not having to remember where your longass > 72 byte passphrase ended than you are getting security from that longass passphrase.
|
# ? Oct 6, 2012 23:06 |
|
Yeah it's more of a worry with some retarded computer generated password file that has 20 xml tags before it because java.Zamujasa posted:Fakedit: Is there a good explanation of how to do this? I'm assuming that it's just using the Blowfish version of php's crypt() function, but if there's a better way and some examples I'm all ears to learning how to do passwords right. Not all crypts have blowfish support. Maybe use phpass and configure it to use bcrypt. It'll do the annoying call to the crypt library for you. The last time I looked at that it would failover to some awful choice if bcrypt were not available, so maybe you should hack the source code to assert that it's actually using bcrypt.
|
# ? Oct 6, 2012 23:45 |
|
|
# ? May 17, 2024 01:28 |
|
Zamujasa posted:Fakedit: Is there a good explanation of how to do this? I'm assuming that it's just using the Blowfish version of php's crypt() function, but if there's a better way and some examples I'm all ears to learning how to do passwords right. As long as you manually pick a large enough cost parameter, yes, plain old PHP crypt() will do the job fine: $hash = crypt('password', '$2y$14$putyoursaltherethanks$'); The 14 here is the cost factor. The higher the cost, the longer it's going to take to generate. An increase of one roughly doubles the time spent. The whole 2a/2x/2y thing has to do with some edge case or another. Be sure to RTFM and check the constants before using it.
|
# ? Oct 6, 2012 23:52 |