views:

8104

answers:

9

I'm not sure how password hashing works (will be implementing it later), but need to create database schema now.
I'm thinking of limiting passwords to 4-20 characters, but as I understand after encrypting hash string will be of different length.
So, how to store these passwords in the database?

+4  A: 

As a fixed length string (VARCHAR(n) or however MySQL calls it). A hash has always a fixed length of for example 12 characters (depending on the hash algorithm you use). So a 20 char password would be reduced to a 12 char hash, and a 4 char password would also yield a 12 char hash.

Treb
+1  A: 

I've always tested to find the MAX string length of an encrypted string and set that as the character length of a VARCHAR type. Depending on how many records you're going to have, it could really help the database size.

Stephen
+2  A: 

You might find this Wikipedia article on salting worthwhile. The idea is to add a set bit of data to randomize your hash value; this will protect your passwords from dictionary attacks if someone gets unauthorized access to the password hashes.

Dana the Sane
That is indeed very worthwhile (+1), but it doesn't answer the question! (-1)
Bill Karwin
Yes, but definitely relevant in this context (+1)
Treb
A: 

At the moment I MD5 the password field in my MySQL databases. The MD5 of any string comes out to be 32 characters long, so I use a VARCHAR(32).

Darryl Hein
Why VARCHAR(32) and not CHAR(32), if the string is always 32 characters?
Bill Karwin
+5  A: 

You can actually use CHAR(length of hash) to define your datatype for MySQL because each hashing algorithm will always evaluate out to the same number of characters. For example, SHA1 always returns a 40-character hexadecimal number.

Noah Goodrich
+1  A: 

It really depends on the hashing algorithm you're using. The length of the password has little to do with the length of the hash, if I remember correctly. Look up the specs on the hashing algorithm you are using, run a few tests, and truncate just above that.

Abyss Knight
+1  A: 

Hashes are a sequence of bits (128 bits, 160 bits, 256 bits, etc., depending on the algorithm). Your column should be binary-typed, not text/character-typed, if MySQL allows it (SQL Server datatype is binary(n) or varbinary(n)). You should also salt the hashes. Salts may be text or binary, and you will need a corresponding column.

Justice
+23  A: 

It depends on the hashing algorithm you use. Hashing always produces a result of the same length, regardless of the input. It is typical to represent the binary hash result in text, as a series of hexadecimal digits.

  • MD5 generates a 128-bit hash value, which can be represented in CHAR(32)
  • SHA-1 generates a 160-bit hash value, which can be represented in CHAR(40)
  • SHA-224 generates a 224-bit hash value, which can be represented in CHAR(56)
  • SHA-256 generates a 256-bit hash value, which can be represented in CHAR(64)
  • SHA-384 generates a 384-bit hash value, which can be represented in CHAR(96)
  • SHA-512 generates a 512-bit hash value, which can be represented in CHAR(128)

NIST recommends using SHA-256 or higher for passwords. Lesser hashing algorithms have their uses, but they are known to be crackable.

You should salt your passwords before applying the hashing function. Salting a password does not affect the length of the hash result.

Bill Karwin
Salting can be done by prefixing a unique value (e.g. the username) to every password. Here's an article that explains why it is necessary: http://www.codinghorror.com/blog/2007/09/rainbow-hash-cracking.html. In short, it helps prevent password cracking attempts that use the rainbow attack method.
Hippo
@Hippo: Please, don't use the username as the salt. Generate a random salt per user.
Bill Karwin
@Bill Is the randomly generated salt stored in the same table row too?
Hippo
Yes, there's no reason not to store it in the same row. Even if an attacker gains access to your database, they'd have to construct their rainbow table based on that salt. And that's just as much work as simply guessing the password.
Bill Karwin
A: 

for md5 vARCHAR(32) is appropriate. For those using AES better to use varbinary.

Hare Srinivasa