2 Answers
2

Theoretically, decoding or not decoding does not matter, because Base64-encoding is a public permutation (every sequence of Base64 characters can be decoded, and reencoded, by everybody, and this is deterministic). If Base64-encoding strengthen or weakens your password hashing function, and your password hashing function is poor and weak and should be replaced with something stronger.

In practice, some password hashing functions have limitations; in particular, most bcrypt implementations accept passwords of size up to 51 or 55 bytes, no more. Since Base64 encoding increases the data size (every 3 bytes yield 4 characters, reencoded as 4 bytes), hashing the Base64 encoding implies a lower maximum password size. For that reason, it is advisable to decode the Base64 and process the raw password.

However there is also a good reason not to decode the Base64, depending on your support library. If your password hashing implementation uses strings as input, then that code necessarily does some character-to-bytes encoding. This can imply some very inconvenient encoding issues, especially with non-ASCII characters (a simple latin-1 character like "é" has several representations in Unicode, yielding different byte sequences). It is important that this encoding is deterministic (when the password is verified, it should use the same encoding as when it was initially chosen). When you receive Base64, then the caller already did the job and presumably agrees with himself. Therefore, it is advisable not to decode the Base64, and instead to hash it directly.

Or maybe not. An alternative view is that encoding issues call for systematic processing, and it may be a good idea to systematically decode everything you receive, to ensure reencoding with the same rules (the encoding rules on the server). This might actually help if the user employs different kinds of client software, with different encoding rules.

So, really, it is up to you. Personally, I would decode the Base64, because I trust me more than other people to process Unicode strings properly, and it avoids artificially lowering the maximum password size in case the hashing function is bcrypt (other functions like PBKDF2 do not have such limitations).

That's up to you, there isn't any less or any more security when it comes to storing those passwords. Kirkhoffs principle dictates that the security of an encryption system should not be compromised if the algorithm falls into the enemy's hands.

So this means that if the attacker knows your scheme, he would not have any extra steps to take care about except base64 encoding the password before trying to bruteforce. While this could mean it would take an extra bit of time to bruteforce the passwords, it's negligeable compared to the overhead of your password hashing algorithm. (providing you took a good one like PBKDF2, scrypt or bcrypt)

I meant it for the attacker snooping on the transmission, if you see a string that looks like base64, it's trivial to extract end decode it. All that happening before he hashes things.
–
MarcinJan 23 '14 at 15:18

That doesn't really matter either. Regardless what alrogithm you use, if an attacker can eavesdrop ( so not using SSL) you can always get the shared secret. Regardless if it's plain, hashed or encoded.
–
Lucas KauffmanJan 23 '14 at 15:21