Scrypt, Bcrypt or anything else

9

I am choosing a hash algorithm for the passwords of a system I develop. At the beginning of my "programmatic" I used MD5 , SHA-1 and its derivants. After a while I chose Whirlpool and now I'm looking for something more robust.

I'm in doubt between Scrypt and others ... About Scrypt I did not like your output:

$s0$e0801$epIxT/h6HbbwHaehFnh/bw==$7H0...

Because I found the breakdown by dollar signage very evident for an attacker (at least it was the impression I had).

Today what would be the best way forward? Scrypt , Bcrypt or PBKDF2 or some other path?

After knowing the project Jasypt I chose to go back to good old Whirlpool, I still want to study the algorithms mentioned above, but for now I'm betting on whirlpool .

    
asked by anonymous 27.02.2014 / 19:04

3 answers

2

It depends on your purpose. There are a number of things to evaluate:

  • Time to break the password using brute force;
  • Number of iterations to generate an encrypted string;
  • Number of characters in your password. For example, Bcrypt does not work with more than 55 characters.

Recommended is PBKDF2 , since you did not like the Scrypt output. It has no character limit. It is easier to break than the other two, but performs better. Below is a table comparing the cost in attempts to break the password of each algorithm:

    
27.02.2014 / 19:14
4

On the dollar sign is obvious to an attacker: in fact this does not mean anything. The security of your system lies in the difficulty in making the attack, not in the difficulty of finding out which algorithm was used. For starters, any algorithm that has a faster attack than brute force is broken and should not be used.

Among algorithms that do not have easy attack, that is, they are only broken by brute force, security increases when more costly (in time and money) to make this brute force. And that's where longer hashed algorithms take advantage of fast hashes: an MD5 was built to be calculated quickly, and being "calculated quickly" is bad for security.

Of the 3 algorithms you mention, we can analyze:

  • PBKDF2: The number of iterations is configurable, that is, you can make it take longer to process. But since it requires few circuits for processing and low RAM, it is possible to use video cards (GPUs) or programmable / optimized circuits (such as ASICs). This way it is possible to make a low cost attack.

  • BCrypt: As it makes more intensive use of RAM, the cost / difficulty of making specific hardware to attack it is higher. In this way, it is safer than PBKDF2. And it is in use already has some time, which means that your security has already been tested and has not yet been broken. But the amount of RAM it uses is still not huge, and so the cost of building hardware to break it is higher than that of PBKDF2, but it's not as big as SCrypt.

    li>
  • SCrypt: SCrypt requires a large amount of memory for its calculation (nothing an ordinary PC or server can not provide, but large enough to disrupt the use of GPUs or dedicated hardware). As it's a newer algorithm, it's not the same time as BCrypt being tested in real life, and so it may have some undetected flaw.

A rule to see which one is right for your application: what would be the interest of someone investing money to break the security of your application? If it is something so valuable (eg bank or bitcoins security), use the solution that is most costly to the attacker (Scrypt). If you just need reasonable security, PBKDF2 or BCrypt will be more than enough.

    
27.02.2014 / 19:52
3

In a hash algorithm, only what is being done is secret. Everything else is public (salt, work factor, other parameters). These algorithms are designed to maintain the pre-image resistance (i.e. from the hash if it finds the password) even though everything else about it is known. So the fact that an attacker sees the dollar sign in the code is not relevant (even though by the time he got his hands on his bank he should already know everything about his system).

In addition, other hash algorithms (even the "broken" ones like MD5) will also need at least one salt (to avoid rainbow tables ), and that salt will have to be stored in somewhere, right? What difference does it make if it is in the hash (separated by dollar sign) or another column in the same table (which the attacker also already has)?

On the best algorithm of the three, see the other answers for a comparison. Personally, I believe that PBKDF2 with a high number of iterations should be enough to protect a password (but in reality all three are good enough). And if your system has high security requirements (such as those at or near a bank) then consider using other means than the password to protect your customers' accounts (two-factor authentication, for example).

Update: Let's say that to make an attacker's life more difficult, you can: 1) take the dollar sign from the exit; 2) change the order of the elements. That way, you're transforming:

$s0$e0801$epIxT/h6HbbwHaehFnh/bw==$7H0vsXlY8UxxyW/BWx/9GuY7jEvGjT71GFd6O4SZND0=

in

e0801s07H0vsXlY8UxxyW/BWx/9GuY7jEvGjT71GFd6O4SZND0=epIxT/h6HbbwHaehFnh/bw==

What will the attacker do?

  • Create an account on your site. So he will know 1 password (his own) and the corresponding hash;

  • Read how scrypt works , discovering that it has:

  • A version number. How many s0 have in your string? Only 1:

    e0801  s0  7H0vsXlY8UxxyW/BWx/9GuY7jEvGjT71GFd6O4SZND0=epIxT/h6HbbwHaehFnh/bw==
    
  • The parameters of the algorithm. Well, in that case it is obvious that it is the first group;

  • A salt and a key. Well, in that case it was easy because base64 encoding ended with = and == , so it's easy to find the pieces.

    e0801  s0  7H0vsXlY8UxxyW/BWx/9GuY7jEvGjT71GFd6O4SZND0=  epIxT/h6HbbwHaehFnh/bw==
    
  • What is the salt and what is the key? Well, he knows his own password and hash, so just do 2 tests:

    $s0$e0801$epIxT/h6HbbwHaehFnh/bw==$7H0vsXlY8UxxyW/BWx/9GuY7jEvGjT71GFd6O4SZND0=
    
    $s0$e0801$7H0vsXlY8UxxyW/BWx/9GuY7jEvGjT71GFd6O4SZND0=$epIxT/h6HbbwHaehFnh/bw==
    

    What works, is the format you are using!

  • Although you use base 16 to make it harder to find the boundaries between parts, the work to test all possibilities (within a same hash representation) is minimal compared to the work of trying to break the hash. If the attacker has enough money to make a hash attack, he can do this test in a matter of minutes. You only complicated its implementation in exchange for a few minutes of the attacker's time. Was it worth it?

        
    27.02.2014 / 19:59