Asked  7 Months ago    Answers:  5   Viewed   33 times

I have used unsalted md5/sha1 for long time, but as this method isn't really secure (and is getting even less secure as time goes by) I decided to switch to a salted sha512. Furthermore I want to slow the generation of the hash down by using many iterations (e.g. 100).

My question is whether I should append the salt on every iteration or only once at the beginning. Here are the two possible codes:

Append every time:

// some nice big salt
$salt = hash($algorithm, $salt);

// apply $algorithm $runs times for slowdown
while ($runs--) {
    $string = hash($algorithm, $string . $salt, $raw);
}

return $string;

Append once:

// add some nice big salt
$string .= hash($algorithm, $salt);

// apply $algorithm $runs times for slowdown
while ($runs--) {
    $string = hash($algorithm, $string, $raw);
}

return $string;

I first wanted to use the second version (append once) but then found some scripts appending the salt every time.

So, I wonder whether adding it every time adds some strength to the hash. For example, would it be possible that an attacker found some clever way to create a 100timesSha512 function which were way faster than simply executing sha512 100 times?

 Answers

37

In short: Yes. Go with the first example... The hash function can lose entropy if feed back to itself without adding the original data (I can't seem to find a reference now, I'll keep looking).

And for the record, I am in support of hashing multiple times.

A hash that takes 500 ms to generate is not too slow for your server (considering that generating hashes are typically not done the vast majority of requests). However a hash that takes that long will significantly increase the time it will take to generate a rainbow table...

Yes, it does expose a DOS vulnerability, but it also prevents brute force attacks (or at least makes them prohibitively slow). There is absolutely a tradeoff, but to some the benefits exceed the risks...

A reference (more like an overview) to the entire process: Key Strengthening

As for the degenerating collisions, the only source I could find so far is this discussion...

And some more discussion on the topic:

  1. HEKS Proposal
  2. SecurityFocus blog on hashing
  3. A paper on Oracle's Password Hashing Algorithms

And a few more links:

  1. PBKDF2 on WikiPedia
  2. PBKDF2 Standard
  3. A email thread that's applicable
  4. Just Hashing Is Far From Enough Blog Post

There are tons of results. If you want more, Google hash stretching... There's tons of good information out there...

Wednesday, March 31, 2021
 
radmen
answered 7 Months ago
95

Prefix or suffix is irrelevant, it's only about adding some entropy and length to the password.

You should consider those three things:

  1. The salt has to be different for every password you store. (This is quite a common misunderstanding.)
  2. Use a cryptographically secure random number generator.
  3. Choose a long enough salt. Think about the birthday problem.

There's an excellent answer by Dave Sherohman to another question why you should use randomly generated salts instead of a user's name (or other personal data). If you follow those suggestions, it really doesn't matter where you put your salt in.

Tuesday, June 1, 2021
 
mario
answered 5 Months ago
80

The code that you have given is a port of PHPASS, specifically the "portable" algorithm. Note the qualification of portable. This will only apply to the phpass library if you pass true as the second constructor parameter. From here on out in this answer, phpass refers ONLY to the portable algorithm, and not the library itself. The library will do bcrypt by default if you do not explicitly specify portable...

The PHPBB team did not develop this themselves (a very good thing), but ported it from phpass directly (arguable).

There are a few questions we should ask here:

Is It Bad?

The short answer is no, it's not bad. It offers pretty good security. If you have code on this right now, I wouldn't be in a rush to get off it. It's adequate for most usages. But with that said, there are far better alternatives if you were starting a new project that I wouldn't pick it.

What are some weaknesses?

  • Relative To pbkdf2: The phpass algorithm uses hash() where pbkdf2() uses hash_hmac(). Now, a HMAC runs 2 hashes for every call internally, but the PHP implementation only takes approximately 1.6 times the execution of a single call to hash() (isn't C wonderful?). So we get 2 hashes from hash_hmac in 62% of the time it would take hash() to execute 2 hashes.

    What does that mean? Well, for a given runtime, pbkdf2 will run approximately 37.5% more hashes than the phpass algorithm. More hashes in a given time == good, because it results in more computation being performed.

    So pbkdf2 is approximately 37.5% stronger than phpass when using the same primitive (md5 in this case). But pbkdf2 can also take stronger primitives. So we can use pbkdf2 with sha512 to gain a very significant advantage over the phpass algorithm (mainly because sha512 is a harder algorithm with more computation than md5).

    This means that not only is pbkdf2 able to generate more computations in the same amount of time, it's able to generate harder computations.

    With that said, the difference isn't overly significant. It's very much measurable, and pbkdf2 is definitely "stronger" than phpass.

  • Relative To bcrypt: This is a lot harder of a comparison to make. But let's look at the surface of it. phpass uses md5, and a loop in PHP. pbkdf2 uses any primitive (in C) and a loop in PHP. bcrypt uses a custom algorithm all in C (meaning it's a different algorithm from any available hash). So right of the bat, bcrypt has a significant advantage just do to the fact that the algorithm is all in C. This allows for more "computation" per unit time. Thereby making it a more efficient slow algorithm (more computations in the given runtime).

    But just as important as how many computations it does is the quality of the computations. This could an entire research paper, but in short it comes down to the fact that the computations that bcrypt uses internally are much harder to perform than a normal hash function.

    One example of the stronger nature of bcrypt is the fact that bcrypt uses a far larger internal state than a normal hash function. SHA512 uses a 512 bit internal state to compute against a block of 1024 bits. bcrypt uses instead about 32kb of internal state to compute against a single block of 576 bits. The fact that bcrypt's internal state is so much bigger than SHA512 (and md5 and phpass) partially accounts for the stronger nature of bcrypt.

Should It Be Avoided

For new projects, absolutely. It's not that it's bad. It isn't. It's that there are demonstrably stronger algorithms out there (by orders of magnitude). So why not use them?

For further proof of how bcrypt is stronger, check out the Slides from Password13 (PDF) which launched a 25 GPU cluster for cracking password hashes. Here are the relevant results:

  • md5($password)
    • 180 BILLION guesses per second
    • 9.4 Hours - All possible 8 character passwords
  • sha1($password)
    • 61 BILLION guesses per second
    • 27 Hours - All possible 8 character passwords
  • md5crypt (which is very similar to phpass with a cost of 10):
    • 77 Million guesses per second
    • 2.5 Years - All possible 8 character passwords
  • bcrypt with a cost of 5
    • 71 Thousand guesses per second
    • 2700 Years - All possible 8 character passwords

Note: all possible 8 character passwords are using a 94 character set:

a-zA-Z0-9~`!@#$%^&*()_+-={}|[]:";'<>,.?/

The Bottom Line

So if you're writing new code, without a doubt use bcrypt. If you have phpass or pbkdf2 in production now, you may want to upgrade, but it's not a clear cut "you're significantly vulnerable".

Monday, August 9, 2021
 
dimi
answered 3 Months ago
37

I got solution by doing little search.

Just generate all required hashes using own server. After getting all required hashes we need to make PayuHashes Obj using this hashes and pass this Obj in intent like this

Intent intent= new Intent(this, PayUBaseActivity.class);
intent.putExtra(PayuConstants.PAYU_CONFIG, payuConfig);
intent.putExtra(PayuConstants.PAYMENT_PARAMS, mPaymentParams);
intent.putExtra(PayuConstants.PAYU_HASHES, payuHashes);
intent.putExtra(PayuConstants.SALT, salt);

PayU SDK will take care of rest

Sunday, August 29, 2021
 
Andras Zoltan
answered 2 Months ago
15

This is not a solution for cryptography. No matter the cipher used, the key will be equally accessible to the attacker. Cyrpto doesn't solve all problems.

chmod 400 is best, this makes it read only. chmod 600 is read write, which may or may not be a requirement. Also make sure its chown'ed by the the process that needs it. This is really the best you can do. Even if you are sharing the machine with other users they shouldn't be able to access it. Hopefully this is a dedicated machine, in that case there isn't much of a threat. SELinux or AppArmor will help harden the system from cross process/cross user attacks.

Edit: shred is the tool you need to securely delete files.

Edit: Based on Moron/Mike's comments the unix command ps aux will display all running processes and the command used to invoke them. For instance the following command will be exposed to all users on the system: wget ftp://user:password@someserver/somefile.ext. A secure alternative is to use the CURL library. You should also disable your shells history. In bash you can do this by setting an environment variable export HISTFILE=

Wednesday, September 22, 2021
 
Chris McCall
answered 1 Month ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :