Pernambuco



  • Once upon 2006 I was working with some enterprise application. As usual, the customer cared more about useless features and senseless constraints that make it seem like the specs were written by the Jigsaw Killer.

    One day, one of the PHB's in the project mandated that no passwords for the system could have repeated characters (besides the other rules already in place, like requiring both numbers and characters). I told him this added no security at all and questioned if he thought a password like "abcde" was safer than "superunconstituional" just because the former had no recurring characters. But, as he said, "I have already talked to a security specialist about this, and he says it's much, much safer this way". I love it when they trust random people they've probably met in a bar more than they trust their own devs.

    By the way... With this change, he also wanted everybody to come up with a new password. So about 60 people had to come up with something that didn't have two of the same character at all, had to be 10 characters long and mix numbers and letters. Some users were having a hard time coming up with something that didn't repeat any character for such a length, and emails were sent to the helpdesk about the new rule.

    So I answered one of the emails like this: "Come on, people, it's not that hard. Can't you really think of a short phrase or a couple words with distinct letters?..."

    Pause. By now I should tell if you Pernambuco. It's one of the largest cities in Brazil, on the northeasetern coast, and it's also an important economical center. Also, some users were from there. Back to my email...

    "... If you think about the biggest cities in Brazil, Pernambuco sure comes up by the top of the list. Now think about it, it's ten characters long with no repetitions. Add a '1' to its end and you got a valid password. I'll leave it up to you guys to come up with other passwords from this point on."

    A week later, and I was talking to a colleague about our security scheme. We were thinking about the things that really matter when it comes to data safety, and were still learning most of what we know today. We had just learned about salting hashes (we did store hashes in the database, but didn't salt them), so we thought, why don't we do it from now on? But before that, we took a snapshot of the database, so we could restore the data if we broke it somehow. So I took a peek into the user table, and noticed that over 80% of the password hashes were about the same. My buddy was scratching his head at this... Couldn't be a bug in the password storing code, people were signing in normally. The only good explanation was that people must have been all using the same password. Memories and ideas started forming in my head, and then I had to try something.

    So I changed my password to "Pernambuco1". Yes, the hash came out just the same as we saw for the bulk of our users. By the same techinique we also found some using "Pernambuco2".

    So I told the PHB about it, and he came up with a new rule. No two people could have the same password. You try to use an already taken password, you get an error message telling you about it. In a system where everybody can see everybody else's usernames, that would be [insert your favorite obscene expression from your native language here]. Specially with the mindset most of them used to create their passwords.

    At least they granted my wish by allowing me to work with some other system. I refused to implement that.



  •  This story almost made me cry.



  • So, I take it another requirement was that all the password rules apply for all employees except that PHB?

     

    Another thing:[quote user="Renan "C#" Sousa"]"I have already talked to a security specialist about this, and he says it's much, much safer this way". I love it when they trust random people they've probably met in a bar more than they trust their own devs.[/quote][quote user="Renan "C#" Sousa"]We [...] were still learning most of what we know today. We had just learned about salting hashes...[/quote]I agree that the PHB was an idiot. But I can kind of understand him here..


  • 🚽 Regular

    You should check how many people chose abcde.



  • O also the password "qwertyuiop1"



  • Password rules are neither good nor bad.

    Rules that increase entropy (must contain at least one of each of the following; letter, number, symbol) are good.

    Rules that decrease entropy (can only contain one of any letter) are bad.

    The PHB has no idea what he is talking about, regardless of salting the hash.  How you store and the rules to generate are completly separated concerns.



  • @KattMan said:

    Password rules are neither good nor bad.

    Rules that increase entropy (must contain at least one of each of the following; letter, number, symbol) are good.

    Rules that decrease entropy (can only contain one of any letter) are bad.

    The PHB has no idea what he is talking about, regardless of salting the hash.  How you store and the rules to generate are completly separated concerns.

     

    All password rules decrease entropy.  


  • ♿ (Parody)

    @Bumble Bee Tuna said:

    All password rules decrease entropy.

    In a theoretical sense you are correct, of course. In the world of human psychology and activity, not necessarily.



  • @Bumble Bee Tuna said:

    @KattMan said:

    Password rules are neither good nor bad.

    Rules that increase entropy (must contain at least one of each of the following; letter, number, symbol) are good.

    Rules that decrease entropy (can only contain one of any letter) are bad.

    The PHB has no idea what he is talking about, regardless of salting the hash.  How you store and the rules to generate are completly separated concerns.

     

    All password rules decrease entropy.  

    well there you go, All rules are therefore bad

     



  • @KattMan said:

    well there you go, All rules are therefore bad
    That's my favorite rule!



  • +1 on the WTF



  • @hoodaticus said:

    @KattMan said:
    well there you go, All rules are therefore bad
    That's my favorite rule!
     

    that's the only good rule



  • @Bumble Bee Tuna said:

    All password rules decrease entropy.  

     

    Entropy != size of domain.



  • Renan, I am disappoint.

    What you should have done was change the app so it only applies the unique-characters-in-password rule when the PHB responsible for said rule attempts to log in.



  • I particularly like when these rules are applied to corporate Blackberry devices.  "Must contain one symbol or number" means that every Blackberry password sequence must contain the "alt" key (which is like a shift key for symbols and numbers) or zero, since zero is the only symbol that doesn't require "alt." By using zero, you save yourself one keypress on a password which must be entered many many times per day.

    Guess what most of our Blackberry passwords start with? Would you also like to guess that the rest of the password is a straight line radiating out from zero on the Blackberry keyboard? I bet that dictionary only has about 10 words in it.

    [The "sym" symbol key can also be used in a password to type a symbol but it behaves differently when used as the first key in the password and it is generally a much rarer key to use anyway.]

    Then the Blackberry password-change application requires you to enter the password twice before it tells you that you have failed the password rules. That resulted in a few "dropped" Blackberries before we let on a few hints on the use of the zero key.



  • [quote user="Renan "C#" Sousa"]So I took a peek into the user table, and noticed that over 80% of the password hashes were about the same.[/quote]

     

    If the password hashes were about the same, there is something very wrong with your hashing technique.  Two similar strings should hash to completely different values. 

    Maybe you meant exactly the same?



  • @ShatteredArm said:

    @Bumble Bee Tuna said:

    All password rules decrease entropy.  

     

    Entropy != size of domain.

     

    Right. It's the  log2 of the size of the domain.


  • ♿ (Parody)

    @Bumble Bee Tuna said:

    @ShatteredArm said:
    @Bumble Bee Tuna said:
    All password rules decrease entropy.

    Entropy != size of domain.

    Right. It's the log2 of the size of the domain.

    There you go again. You're just thinking about the maximum possible entropy. Not the actual, or even likely, entropy of the actual passwords that people will use. This is only really worth thinking about in this sense if we all use random generators. But I think we all know that not enough people do that.



  • @boomzilla said:

    @Bumble Bee Tuna said:
    @ShatteredArm said:
    @Bumble Bee Tuna said:
    All password rules decrease entropy.
    Entropy != size of domain.
    Right. It's the log2 of the size of the domain.
    There you go again. You're just thinking about the maximum possible entropy. Not the actual, or even likely, entropy of the actual passwords that people will use. This is only really worth thinking about in this sense if we all use pseudo random generators. But I think we all know that almost nobody do that.

    FTFY



  • @frits said:

    [quote user="Renan "C#" Sousa"]So I took a peek into the user table, and noticed that over 80% of the password hashes were about the same.

     

    If the password hashes were about the same, there is something very wrong with your hashing technique.  Two similar strings should hash to completely different values. 

    Maybe you meant exactly the same?

    [/quote]

    Sorry, non native English speaker here. You're right, and lemme rephrase that... About 80% of the password hashes were exactly the same. We used MD5.



  • @Bumble Bee Tuna said:

    @ShatteredArm said:


    Entropy != size of domain.

    Right. It's the  log2 of the size of the domain.


    Only if everything in the domain is equally likely. When we're talking passwords, that's certainly not the case. If 70% of your users would choose a password made entirely out of lower-case letters in the absence of any password restrictions, adding restrictions such as "must include an uppercase letter" and "must include a digit" will increase password entropy. Unless you're foolish enough to give them an example of a valid password.



  • [quote user="Renan "C#" Sousa"]had to be 10 characters long[/quote]

    [quote user="Renan "C#" Sousa"]Pernambuco...ten characters long with no repetitions. Add a '1' to its end and you got a valid password[/quote]

    Wait, what?



  • @bertram said:

    [quote user="Renan "C#" Sousa"]had to be 10 characters long

    [quote user="Renan "C#" Sousa"]Pernambuco...ten characters long with no repetitions. Add a '1' to its end and you got a valid password[/quote]

    Wait, what?[/quote]

    You are an pedantic dickweed. Just add an "at least" to the first sentence mentally.



  • [quote user="Renan "C#" Sousa"]We used MD5.[/quote] 

    IT IS 2011. STOP USING MD5. MD5 IS OLD. MD5 IS FAST. MD5 IS WEAK. MD5 IS BROKEN. MD5 IS WHY WE CAN'T HAVE NICE THINGS.

    You'r salting them, right? I mean, you mention learning about salts, but I'm not clear on whether the current state of things is salted pretzels hashes.


  • ♿ (Parody)

    [quote user="Renan "C#" Sousa"]
    Once upon 2006...
    [/quote]
    @dhromed said:

    IT IS 2011.

    Ahem.



  • @boomzilla said:

    [quote user="Renan "C#" Sousa"] Once upon 2006...
    @dhromed said:
    IT IS 2011.

    Ahem.[/quote] 

    WELL.

     

    OKAY.



  • @dhromed said:

    [quote user="Renan "C#" Sousa"]We used MD5.

     

    IT IS 2011. STOP USING MD5. MD5 IS OLD. MD5 IS FAST. MD5 IS WEAK. MD5 IS BROKEN. MD5 IS WHY WE CAN'T HAVE NICE THINGS.

    You'r salting them, right? I mean, you mention learning about salts, but I'm not clear on whether the current state of things is salted pretzels hashes.

    [/quote]


    people always repeat that MD5 is weak, is broken etc.

    i do not agree.

    but in this case there is a way to show me that i'm wrong, if you are up to it, i will post 10 MD5 presalted pretzelshashes in coder challenge.

    i anyone cracks it, i will agree that MD5 is weak, old, broken etc. and spend the rest of my days guessing passwords from users of legacy applications and silently moving these applications to bcrypt


  • Discourse touched me in a no-no place

    @Nelle said:

    people always repeat that MD5 is weak, is broken etc.

    i do not agree.
    It's unsuitable for hashing passwords because it's too quick. Google key stretching sometime.



  • @Nelle said:

    i do not agree.

    Instead of linking to the wikipedia article, I'll link to two prominent sources for that article.

    Software developers, Certification Authorities, website owners, and users should avoid using the MD5 algorithm in any capacity. As previous research has demonstrated, it should be considered cryptographically broken and unsuitable for further use.



  • @dhromed said:

    @Nelle said:
    i do not agree.

    Instead of linking to the wikipedia article, I'll link to two prominent sources for that article.

    Software developers, Certification Authorities, website owners, and users should avoid using the MD5 algorithm in any capacity. As previous research has demonstrated, it should be considered cryptographically broken and unsuitable for further use.

    The reason cited in those articles is the ability to create collisions.  Doesn't using a salt mitigate this risk?


  • Discourse touched me in a no-no place

    @frits said:

    The reason cited in those articles is the ability to create collisions.  Doesn't using a salt mitigate this risk?
    Only in that it's unlikely that there's a pre-generated rainbow table with the salted passwords in. Otherwise the chance of a collision is the same with or without the salt.



  • @frits said:

    Doesn't using a salt mitigate this risk?
     

    Yes.

    Salting is a solution to rainbow tables, because it restores the burden of computing for the attacker.

    However, MD5 is a very fast algorithm. Combined with the power of today's consumer hardware, that burden is no longer much of an issue.



  • @dhromed said:

    @frits said:

    Doesn't using a salt mitigate this risk?
     

    Yes.

    Salting is a solution to rainbow tables, because it restores the burden of computing for the attacker.

    However, MD5 is a very fast algorithm. Combined with the power of today's consumer hardware, that burden is no longer much of an issue.

    And it's one fucking line of code. Just replace "md5" in your crypt function call. Christ. People spend more time pissing and moaning than they do making the fucking fix.



  • @blakeyrat said:

    People spend more time pissing and moaning [b]learning about the issue[/b] than they do making the fucking fix.

    FTFY. (Granted, some folks don't learn gracefully, but it's ultimately always about the education process.)



  •  @Xyro said:

    FTFY. (Granted, some folks don't learn gracefully, but it's ultimately always about the education process.)

    +2



  • @blakeyrat said:

    @dhromed said:

    @frits said:

    Doesn't using a salt mitigate this risk?
     

    Yes.

    Salting is a solution to rainbow tables, because it restores the burden of computing for the attacker.

    However, MD5 is a very fast algorithm. Combined with the power of today's consumer hardware, that burden is no longer much of an issue.

    And it's one fucking line of code. Just replace "md5" in your crypt function call. Christ. People spend more time pissing and moaning than they do making the fucking fix.

    What am I fixing again?  How would I convert my database full of md5 hashes into the new hashes you propose (SHA-512 or whatever)?  Is that one line of code too?

    This all purely hypothetical, since I don't really do this kind of coding. 



  • @frits said:

    Is that one line of code too?

    Yes. I'm sorry, I thought this was a forum for software engineers, not crying infants who need their binkies.

    function CheckPassword( username, passwordHash )
    {
     if( passwordHash == MD5HashForUser( username ) || passwordHash == BetterHashForUser( username ) )
     {
      YoureIn();
      return;
     }
     YoureOutGoAway();
    }

    Of course whenever you store a new password, either as a result of a password change or new user, you'd use BetterHashForUser() and not MD5HashForUser().

    Now what you could also do is check for MD5 hashes and the last time the user changed the password, and if they've had the old MD5 hash for a year or so you could expire their password. That's how Amazon.com made the transition with minimal impact to customers.



  • Surely you're missing something?



  • @frits said:

    Surely you're missing something?

    Fuck. It's psuedo-code, you pedantic dickweed.

    HERE'S MY ASSUMPTION: that the FAKE PSUEDOCODE FUNCTION BetterHashForUser() DOES ALL THE GOOD SECURITY STUFF YOU SHOULD BE DOING. INCLUDING SALT. Ok? Happy?



  • @blakeyrat said:

    @frits said:

    Surely you're missing something?

    Fuck. It's psuedo-code, you pedantic dickweed.

    HERE'S MY ASSUMPTION: that the FAKE PSUEDOCODE FUNCTION BetterHashForUser() DOES ALL THE GOOD SECURITY STUFF YOU SHOULD BE DOING. INCLUDING SALT. Ok? Happy?

    Did you miss this part?

    @me said:

    This all purely hypothetical, since I don't really do this kind of coding. 

    Hence, I wasn't asking for any code from anyone.  Anyway...

     



  • @frits said:

    @me said:

    This all purely hypothetical, since I don't really do this kind of coding. 

    Hence, I wasn't asking for any code from anyone.  Anyway...

    Ok, seriously. Look:

    1) If you are a software engineer, and you can't figure out how to convert a database of passwords from MDS to a better hash (whatever it may be), you should resign right now and go dig ditches or something because you suck. Thus the "infant" comment.

    2) If you understand the concept of "hypothetical", how is it you do not understand the concept of "psuedocode"?

    3) If you don't care for the answer, why the fuck were you being a pedantic dickweed about it?


  • ♿ (Parody)

    @blakeyrat said:

    3) If you don't care for the answer, why the fuck were you being a pedantic dickweed about it?

    I don't care who you are....that's funny!



  • @blakeyrat said:

    @frits said:

    @me said:

    This all purely hypothetical, since I don't really do this kind of coding. 

    Hence, I wasn't asking for any code from anyone.  Anyway...

    Ok, seriously. Look:

    1) If you are a software engineer, and you can't figure out how to convert a database of passwords from MDS to a better hash (whatever it may be), you should resign right now and go dig ditches or something because you suck. Thus the "infant" comment.

    2) If you understand the concept of "hypothetical", how is it you do not understand the concept of "psuedocode"?

    3) If you don't care for the answer, why the fuck were you being a pedantic dickweed about it?

    You're begging lots of questions here.  This all started because I asked someone if salting mitigated the risk of collisions for MD5 hashes.  I was genuinely curious.  Then you started ranting about "one line of code" and "bitching and moaning".  So I went with it.  Anyway, it was fun while it lasted, but this has shifted to something else completely.  You win, I guess.



  • @blakeyrat said:

    @frits said:
    Is that one line of code too?

    Yes. I'm sorry, I thought this was a forum for software engineers, not crying infants who need their binkies.

     

    function CheckPassword( username, passwordHash )
    {
     if( passwordHash == MD5HashForUser( username ) || passwordHash == BetterHashForUser( username ) )
     {
      YoureIn();
      return;
     }
     YoureOutGoAway();
    }

    Of course whenever you store a new password, either as a result of a password change or new user, you'd use BetterHashForUser() and not MD5HashForUser().

    Now what you could also do is check for MD5 hashes and the last time the user changed the password, and if they've had the old MD5 hash for a year or so you could expire their password. That's how Amazon.com made the transition with minimal impact to customers.

     

    Better still: hang on to both hashes of whatever password they entered when entering the above pseudocode.  If BetterHashForUser() matches, proceed as above.  If MD5HashForUser() matches instead, update the database with the BetterHashForUser() hash so that from then on they're actually using that one.

     



  • @da Doctah said:

    Better still: hang on to both hashes of whatever password they entered when entering the above pseudocode.  If BetterHashForUser() matches, proceed as above.  If MD5HashForUser() matches instead, update the database with the BetterHashForUser() hash so that from then on they're actually using that one.

    That is a better idea. +1.



  • @serguey123 said:

    @boomzilla said:

    @Bumble Bee Tuna said:
    @ShatteredArm said:
    @Bumble Bee Tuna said:
    All password rules decrease entropy.
    Entropy != size of domain.
    Right. It's the log2 of the size of the domain.
    There you go again. You're just thinking about the maximum possible entropy. Not the actual, or even likely, entropy of the actual passwords that people will use. This is only really worth thinking about in this sense if we all use pseudo random generators. But I think we all know that almost nobody does that.

    FTFY

     

    FTFY

     



  • @frits said:

    Software developers, Certification Authorities, website owners, and users should avoid using the MD5 algorithm in any capacity. As previous research has demonstrated, it should be considered cryptographically broken and unsuitable for further use.

    The reason cited in those articles is the ability to create collisions.  Doesn't using a salt mitigate this risk?

     

     

    ...doesn't using a salt only creates another md5 to which you can find a collision string?

    (...do you salt before creating a hash, or after? the latter seems to make sense to me, but the former makes my previous statement/question valid, i guess)

    ((yes, TRWTF is me, not really bothering to understand salts, as i've never needed to use them so far, i know what they are, but obviously, my shallow "yeah, i know what it is" knowledge is not enough))

     


  • Discourse touched me in a no-no place

    @SEMI-HYBRID code said:

    ...doesn't using a salt only creates another md5 to which you can find a collision string?
    Yes. That's the whole point of a salt - to produce a different hash. Using a different salt for each user means that everyone who uses password123 as their password, for example, ends up with a different hash in your password database, whereas unsalted, they would all have the same hash of 482c811da5d5b4bc6d497ffa98491e38.
    @SEMI-HYBRID code said:
    ...do you salt before creating a hash, or after?
    Usually before.



  • @Nelle said:


    people always repeat that MD5 is weak, is broken etc.
    i do not agree.
    but in this case there is a way to show me that i'm wrong, if you are up to it, i will post 10 MD5 presalted pretzelshashes in coder challenge.
    i anyone cracks it, i will agree that MD5 is weak, old, broken etc. and spend the rest of my days guessing passwords from users of legacy applications and silently moving these applications to bcrypt

    Have a look at http://valerieaurora.org/hash.html

    Once a serious flaw is found, you should start migrating if you haven't already. If you wait until someone publishes the code to break first and second pre-image resistance then it's too late.

    On the migration by checking both hashes: there's another implementation detail. Take advantage of the transition to make the hash document itself. You need to store the salt in the DB anyway to create the hash; store the algorithm name too. That way when you make the next transition you eliminate the guessing.



  • @SEMI-HYBRID code said:

    ...doesn't using a salt only creates another md5 to which you can find a collision string?
     

    OK, here's the thing.

    1. You have passwords.

    2. Database stolen? => You're fucked

    3. Hash them!

    4. Database stolen? Now the attacker has no passwords, and he has to bruteforce the password. This is prohibitively expensive.

    5. Enter: rainbow tables.

    6. Database stolen? Now the attacker just needs to look up the hash to find a common password that produces that hash. => You're fucked.

    7. Salt passwords randombly and hash those! Store salts publicly with the hashed (password + salt).

    8. Database stolen? Now the attacker can't use his rainbow table anymore. => You're safe.

     

    Point 4 and further become meaningless once the hash algorithm and hardware are fast enough. Bruteforcing becomes a viable option. Even worse when the hash algo is broken, because then the attacker doesn't even have to burteforce it.


Log in to reply