Recommended hash for passwords in ASP Classic

11,804

Solution 1

A lot of people seem to be beating on the question-asker because he's looking for a slow hash function. Actually, all other aspects being equal, a slower hash function is more secure than a fast one. This is because a slower hash function results in slower generation of rainbow tables and slower brute forcing or dictionary attacks on the password.

From Thomas Ptacek at http://www.securityfocus.com/blogs/262, as referenced in this Coding Horror article:

The problem is that MD5 is fast. So are its modern competitors, like SHA1 and SHA256. Speed is a design goal of a modern secure hash, because hashes are a building block of almost every cryptosystem, and usually get demand-executed on a per-packet or per-message basis.

Speed is exactly what you don’t want in a password hash function.

Modern password schemes are attacked with incremental password crackers.

Incremental crackers don’t precalculate all possible cracked passwords. They consider each password hash individually, and they feed their dictionary through the password hash function the same way your PHP login page would. Rainbow table crackers like Ophcrack use space to attack passwords; incremental crackers like John the Ripper, Crack, and LC5 work with time: statistics and compute.

The password attack game is scored in time taken to crack password X. With rainbow tables, that time depends on how big your table needs to be and how fast you can search it. With incremental crackers, the time depends on how fast you can make the password hash function run.

The better you can optimize your password hash function, the faster your password hash function gets, the weaker your scheme is. MD5 and SHA1, even conventional block ciphers like DES, are designed to be fast. MD5, SHA1, and DES are weak password hashes. On modern CPUs, raw crypto building blocks like DES and MD5 can be bitsliced, vectorized, and parallelized to make password searches lightning fast. Game-over FPGA implementations cost only hundreds of dollars.

Some comments on the PHP MD5 documentation also discuss preference for slowness.

To answer your question, it looks like BCrypt is the way to go. However, I have not been able to find any implementations for ASP Classic. If that's true, I would stick with a regular hash function like SHA512.

Solution 2

I'll ignore the slow part, and instead go for the "good" part.

I suggest you use SHA-512 with a salt to defeat dictionary and rainbow table attacks. I don't believe there are any known vulnerabilities for SHA-512.

Solution 3

If you are trying to defeat brute force attacks you are better off enforcing some failed attempts window/count rather than relying on the speed of the hashing (or hash comparison) mechanism to make the attack take longer to succeed. Lock out the account after a certain number of failed attempts within the failure window and only let new attempts be made after a significant amount of time has elapsed.

This could leave you open to a DOS attack against a well-known (administrative) account, but you could exempt certain accounts from the lockout policy or have an alternate way -- using a security question/answer -- to logon to a locked out account before the reset period has elapsed.

[EDIT] To help defeat rainbow attacks -- where the attacker has retrieved your hashed passwords and finds suitable matches that hash to the same values -- consider both using a random salt unique to each user's hashed password and a fixed salt that is part of the algorithm, not the data. For example:

  testHash = computeHash( user.salt + "98hloj5674" + password );
  if (testHash == user.hashedPassword)
  {
      valid = true;
  }

This should invalidate the rainbow tables since, even knowing the user's salt and the hash algorithm, the values in the attacker's rainbow tables won't map onto your hashed passwords because of the addition of the fixed salt in the algorithm.

With ASP Classic, you'd have to do this in a library instead of on the page to make sure that the user couldn't see your fixed salt.

Solution 4

Dim sPassword, sSalt
sPassword = "Lorem"
sSalt = "Ipsum"
With CreateObject("CAPICOM.HashedData")
  .Algorithm = 0 ' CAPICOM_HASH_ALGORITHM_SHA1
  .Hash sPassword & sSalt
  Response.Write "Here is your hash: " & .Value
End With

Capicom documentation

Algorithm is any of the following:

CAPICOM_HASH_ALGORITHM_SHA1      = 0
CAPICOM_HASH_ALGORITHM_MD2       = 1
CAPICOM_HASH_ALGORITHM_MD4       = 2
CAPICOM_HASH_ALGORITHM_MD5       = 3
CAPICOM_HASH_ALGORITHM_SHA_256   = 4 - Not supported on Windows XP or 2000
CAPICOM_HASH_ALGORITHM_SHA_384   = 5 - Not supported on Windows XP or 2000
CAPICOM_HASH_ALGORITHM_SHA_512   = 6 - Not supported on Windows XP or 2000
Share:
11,804

Related videos on Youtube

Cory House
Author by

Cory House

Independent consultant, Microsoft MVP (C#), Pluralsight author, Speaker, blogger, and software architect. I currently specialize in creating C# .Net and JavaScript based single page applications for the automotive industry.

Updated on June 04, 2022

Comments

  • Cory House
    Cory House almost 2 years

    What is the slowest (therefore best) hash algorithm for passwords in ASP Classic?

    EDIT: For those unaware, when hashing passwords, slower hashes are preferred to faster to help slow rainbow table style attacks.

    EDIT2: And yes, of course speed isn't the only valid concern for hash selection. My question assumes that All other things being equal, the slowest hash method is preferred when hashing a password. Though collision/reverse engineering is of course a concern too, I'm prioritizing speed in this question since it is arguably the most critical factor to consider when comparing popular hash algorithms for use on passwords.

    Thanks!

    • chills42
      chills42 over 15 years
      You want a "strong" hashing method... but that doesn't necessarily equal "slow" The two often go together though, so I can understand the confusion.
    • Bill the Lizard
      Bill the Lizard over 15 years
      @Jon: Salts force an attacker to use a rainbow table (in place of a dictionary), they don't defeat them.
  • Justin Ohms
    Justin Ohms over 15 years
    You completely miss the point...a slow hash function is slow computationally, which makes it difficult for generate rainbow tables, etc.
  • Maurício
    Maurício over 15 years
    You can double it's efficiency by using "sleep for 20 seconds" ;-)
  • Bill the Lizard
    Bill the Lizard over 15 years
    Salts defeat dictionary attacks, not rainbow tables. An attacker is forced to resort to a rainbow table attack when you add salt.
  • Joel Coehoorn
    Joel Coehoorn over 15 years
    The important thing here is all other aspects being equal. That is rarely the case. Using speed as the primary indicator of strength is a very bad idea.
  • tvanfosson
    tvanfosson over 15 years
    But it's not the hash function, but the hash comparison that you need to slow down -- and even, then, I would argue that you want your normal case to be fast and only slow things down when you detect an attack, say after 10 failed attempts in 15 minutes. Then, slow it down a lot.
  • Jon Skeet
    Jon Skeet over 15 years
    Hang on - just looked it up in wikipedia, and I was right (assuming wikipedia is) - a salt is used to make rainbow table attacks difficult or infeasible. See en.wikipedia.org/wiki/Rainbow_table
  • Justin Ohms
    Justin Ohms over 15 years
    @tvanfosson: your point is valid unless we are assuming that the attacker has access to your raw hashes (and I think we are, as rainbow tables has been assumed as an attack). Then your application's limits won't affect anything; only the speed the hash function will slow him down.
  • Adam Lassek
    Adam Lassek over 15 years
    A rainbow table would still work, but you'd have to generate a new one for each salt -- which is a non-trivial process, to say the least.
  • Justin Ohms
    Justin Ohms over 15 years
    Your logic here is not consistent. You are assuming he wants to protect against rainbow attacks, which require access to the hashes. But if he does have this access, he can also run brute force attacks on the hashes. That's where the speed of the function used comes in.
  • Chris Kite
    Chris Kite over 15 years
    "I rarely find [Whirlpool] implemented by default in various tools and languages." I think you just answered your own question. Additionally, the SHA-2 family of hash functions are FIPS 180-2 approved; Whirlpool is not.
  • Jon Skeet
    Jon Skeet about 15 years
    @gs: But you need to add each salt to each dictionary word, making it hugely more time and space consuming.
  • Jon Skeet
    Jon Skeet over 14 years
    Downvoters: please add a comment, otherwise the vote is relatively useless.
  • tvanfosson
    tvanfosson over 14 years
    He's the one who mentioned rainbow tables, I was just responding to his addition. If he's retrieved your hashed passwords, it won't matter what algorithm or the speed since he basically has infinite time to crack the passwords -- presumably he can farm it out to all of the machines he's cracked already to do it in parallel. The best solution is still to limit the number of failed attempts to defeat brute force attacks (which was the assumption until he edited) and add some fixed salt in addition to the stored salt when computing the hashed password to address issues of compromise.
  • peedeeaay
    peedeeaay over 9 years
    "With ASP Classic, you'd have to do this in a library instead of on the page to make sure that the user couldn't see your fixed salt." How would the user see the salt if it's on-page ie. within code?
  • Digs
    Digs about 9 years
    For anypody reading this years later, here's a SHA512 implementation in Classic ASP amadiere.com/blog/2011/02/c-net-classic-asp-password-hashing