I'm going to run SHA256
on a password + salt, but I don't know how long to make my VARCHAR
when setting up the MySQL database. What is a good length?

- 155,785
- 88
- 678
- 743

- 24,588
- 41
- 96
- 113
-
16Before anyone reading this decides to follow this advice and use `SHA-*` to hash passwords, [PLEASE read this first](https://security.stackexchange.com/questions/16354/whats-the-advantage-of-using-pbkdf2-vs-sha256-to-generate-an-aes-encryption-key). – c00000fd May 10 '17 at 05:31
-
4Unless you’re using SHA-256 on passwords, which you shouldn’t do, the hashes have a length of 256 bits, or 64 hexadecimal characters, or 43 alphanumeric characters, or 32 bytes. – caw Nov 20 '19 at 16:01
-
@c00000fd: I'm not sure that the link is particularly relevant. The OP specifically wants to use a 'password+salt'. If the salt is 16 random characters, for example, then it doesn't matter that SHA-256 is 'fast', and dictionary attacks are then impossible. See the gnu docs for `crypt` for example code. SHA-x is fine for passphrases, as long as you know what you're doing. – EML Sep 13 '21 at 10:36
-
@EML: That link is the correct one for this, and it absolutely does matter that SHA-256 is fast. SHA-x is bad for passphrases, even if you know what you're doing. – President James K. Polk Jan 13 '23 at 13:07
-
@PresidentJamesK.Polk: do the sums. If SHA-x must be run `n` times to break a plain password, then adding a 16-byte salt means that it has to be run `n * 256^16` times instead. Even if the password itself was trivially short - say one printable character - then SHA-x must be run `3 * 10^40` times to test all possibilities. If you've got a GPU setup that runs at 11 billion SHA-256 ops/second, this is `3 * 10^30` seconds. This is *vastly* longer than the age of the universe. Ergo, the fact that SHA-x is "fast" is utterly irrelevant. – EML Jan 13 '23 at 13:44
-
@EML: You are completely misunderstanding the function of the salt. The salt is not a secret. – President James K. Polk Jan 13 '23 at 16:00
-
@PresidentJamesK.Polk: the salt is recorded only in the *hash output*, or equivalently, and *is* a secret, unless the attacker has access to the hashes (in `/etc/shadow`, or wherever). If they have that access, it's game over anyway. If the salt wasn't a secret it would be completely pointless. – EML Jan 13 '23 at 16:15
-
@EML: Stop already, you don't know what you're talking about. Do some research. – President James K. Polk Jan 13 '23 at 16:49
-
@PresidentJamesK.Polk: if you have a point to make, explain why the calculation is incorrect, rather than just explaining how clever you are or how stupid I am. – EML Jan 13 '23 at 19:12
5 Answers
A sha256 is 256 bits long -- as its name indicates.
Since sha256 returns a hexadecimal representation, 4 bits are enough to encode each character (instead of 8, like for ASCII), so 256 bits would represent 64 hex characters, therefore you need a varchar(64)
, or even a char(64)
, as the length is always the same, not varying at all.
And the demo :
$hash = hash('sha256', 'hello, world!');
var_dump($hash);
Will give you :
$ php temp.php
string(64) "68e656b251e67e8358bef8483ab0d51c6619f3e7a1a9f0e75838d41ff368f728"
i.e. a string with 64 characters.

- 4,804
- 4
- 44
- 57

- 395,085
- 80
- 655
- 663
-
7can we use char(64) as the primary key or will binary(32) be better for that? (access_token) – frankish Sep 15 '13 at 10:18
-
4If you think you might want to block a user in the future, then I suggest using `varchar(65)` for a leading `!`... just saying. – Manatax Mar 09 '14 at 21:42
-
142
-
6As you want to have a different salt for each password you have to store this next to the hash. For this you can use an extra field or pre-/append it to the hash, so you will need more than 64 chars – Patrick Cornelissen Apr 24 '15 at 17:21
-
4you can use this select statement to test it: `SELECT length(to_base64(unhex(sha2('say hello to my little friend',256))))` , it is always 44 whatever the length of original string is. – DrAhmedJava Apr 09 '17 at 13:57
-
1If you must use text, base64 encode to save some space, or better yet use a binary field – jjxtra Jul 29 '20 at 14:46
-
PLEASE DON'T JUST SHA-256 A PASSWORD w/ or w/o SALT. Use PBKDF2, bcrypt, or scrypt. If your password database is ever leaked, these are resistant to brute-force reversing. https://medium.com/@kasunpdh/how-to-store-passwords-securely-with-pbkdf2-204487f14e84 – jsears Mar 31 '21 at 19:40
-
@PatrickCornelissen: add the random salt to the *clear* passphrase, hash the *result*, and you still get 256 bits. – EML Sep 13 '21 at 10:38
-
@EML and if you don't store the salt to apply it to the given phrase you want to match with the hash, how would you do that? Having a hash from something with a random salt you don't know anymore is just a random block of bits you dan't do anything useful with. – Patrick Cornelissen Sep 14 '21 at 11:28
-
1@PatrickCornelissen - Ok, that was unclear - I use the Posix/libc `cypt`, and the `crypt` output actually includes the hash, so can be used directly for testing. But the output is more than 256 bits, so, basically, exactly what you said... :) – EML Sep 14 '21 at 14:19
Encoding options for SHA256's 256 bits:
- Base64: 6 bits per char =
CHAR(44)
including padding character - Hex: 4 bits per char =
CHAR(64)
- Binary: 8 bits per byte =
BINARY(32)

- 18,448
- 3
- 51
- 66
-
35Base64 is 3 bytes per 4 chars, so even though 32 bytes fits into 43 characters, you actually need 44. An extra = is added as the final character – Wilco Jun 02 '15 at 21:23
-
5
I prefer to use BINARY(32) since it's the optimized way!
You can place in that 32 hex digits from (00 to FF).
Therefore BINARY(32)!

- 800
- 8
- 15
-
13+1 - I like optimized...to anyone else happening on this...to use this with MySQL...you can use `UPDATE...SET hash_column=UNHEX(sha256HexString)`. Then, when retrieving it, you `SELECT HEX(hash_column) AS hash_column`. – Kevin Nelson Sep 17 '14 at 21:20
-
A pertinent MySQL doc: https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html – Buttle Butkus Sep 30 '21 at 06:25
Why would you make it VARCHAR? It doesn't vary. It's always 64 characters, which can be determined by running anything into one of the online SHA-256 calculators.

- 176,543
- 40
- 303
- 368
-
1
-
32
-
11varchar also doesn’t allocate space unless its used, unlike char it allocates the number of amount of total characters allowed regardless if there is data filling it. – Xenland Feb 11 '13 at 16:44
It will be fixed 64 chars, so use char(64)

- 2,960
- 1
- 21
- 14
-
2
-
Or [BINARY(64)](https://mariadb.com/kb/en/binary/)as you not really dealing with text here. – theking2 Jan 08 '23 at 18:34