11

Assume that I'm using bcrypt with a unique salt (or some other best practice) to hash user passwords before storing them in my database.

  • Is there any security advantage to be gained by character-shifting the password before encrypting? (i.e. A -> B, a -> b, 9 -> :)
  • Is there any security advantage to be gained by character-shifting the hash after encrypting, excluding the ==? (i.e. AB+6/== -> BC,70==)
  • If there's no advantage to be gained, is there any loss of security by doing this? Or is it a wash?

In light of the rise in attacks based on standard password patterns, does obscuring these patterns help at all?

Bobson
  • 1,456
  • 10
  • 12
  • This only helps if the attacker doesn't know the source code of your application. For that case it's easier and stronger to use proper encryption. But since you can't assume that your code remains secret, this should only be used in addition to, not instead of, proper password hashing. – CodesInChaos Oct 17 '13 at 17:44

5 Answers5

24

Applying a transform on passwords before hashing them makes no direct harm to security as long as it is injective: two distinct passwords before apply the transform shall still be distinct once both are transformed. Your "character shifting" is fine for that if you do it properly (i.e. beware of transforming a byte of value 255 into a byte of value 0 which will "truncate" the password).

Indirectly, there is a bit of harm in that your extra transform is extra code, thus extra complexity, and complexity is always bad for security. Moreover, if the transform is computationally expensive, then it comes at odds with the iteration count used in PBKDF2/bcrypt (i.e. you have less CPU available, so you must use a lower iteration count).

A transform like the one you envision makes any good to the security only insofar as the attacker is not aware of it, i.e. the attacker did not do his homework. Basic, low-power attackers who just got lucky with a SQL injection attack may indeed lack the knowledge, but these attackers are not the scary ones. Your extra transform will not deter strong attackers, and that's strong attackers you should worry about.

Transforms applied after hashing have no influence whatsoever on security, except if you are using something like extra hashing, in which case you are just trying to build a custom hash function, which, as usual, is a bad idea. So don't do it. The proper way to use your CPU is not to waste it on voodoo character shifts and other rituals; instead, use your CPU to have a bcrypt/PBKDF2 iteration count as high as is tolerable for your overall application performance.

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949
  • 3
    Also, any transform logic can be generalised into a constant value input to a more universalised version of the `bcrypt()` algorithm. Put simply, from a skilled well-resourced attacker's viewpoint, your unknown transform logic is simply a static global salt. – LateralFractal Oct 18 '13 at 00:08
13

No.

The whole principle of modern cryptography is that you should automatically assume that the attacker knows your crypto scheme. You're treating your scheme as secret, which is a bad idea.

Stick to normal bcrypt / PBKDF2.

Polynomial
  • 132,208
  • 43
  • 298
  • 379
  • See my edits. Do they change anything? – Bobson Oct 17 '13 at 15:46
  • 2
    See Thomas Pornin's answer - he covers everything I'd say anyway. – Polynomial Oct 17 '13 at 16:17
  • The biggest damages caused to cryptographic algorithms is their supposed secrecy. The best historical example is the "Bombe" (http://en.wikipedia.org/wiki/Bombe) which permitted to terminate world war II. Knowing how to break the Enigma gave a leading advantage to the british and americans upon the germans. The germans trusted the secrecy of their algorithm and continued to transmit strategic information with it. To keep secret that a cryptographic algorithm is broken is a **strategic advantage**. To keep secret a cryptographic algorithm is a **strategic failure**. – dan Oct 18 '13 at 08:09
  • @danielAzuelos It's important to note that by 1940s standards the Enigma was an *amazing* piece of cryptographic engineering. They even knew its limitations when they deployed it, and the Allies couldn't break it without capturing a lot of equipment and messages. Its downfall was in the German soldiers misusing the device (key re-use), and that the Allied soldiers managed to capture several Enigmas *and* the corresponding code books. A generic attack was eventually discovered, but it took years of hard work and the biggest purpose-built supercomputers of that era. – Polynomial Oct 18 '13 at 08:53
3

Salting passwords does obscure these patterns. You basically suggest salting two times. Once with your homemade salt and afterwards within bcrypt.

This would only produce additional security in a scenario where you attaker doesn't know your homemade salt but does know the unique salt that you use with bcrypt.

Such a scenario shouldn't happen. The attacker should only know your unique salt for bcrypt if he has access to your whole system and then he also knows your homemade salt.

In general it's best practice to trust the encryption function instead of trying to implement your own one. In this case it means trusting bcrypt to salt properly instead of trying to get salting right yourself.

Christian
  • 1,876
  • 1
  • 14
  • 23
2

What you are doing with shifting the characters, is adding a secret to the hashing process. An attacker has to know (or has to find out) what you did before you calculated the hash, otherwise he cannot use a dictionary to find the original password.

There are better ways to add such a server-side secret. You can encrypt the already hashed password with a block cypher (two-way encryption). To get your key, an attacker not only needs read access to your database (SQL-injection), additionally he must gain privileges on the server to read the key.

➽ With encrypting the password-hash you can prevent dictionary attacks, as long as the key remains secret. The key remains secret, as long as the attacker has no privileges on the server.

This is the same advantage a pepper can give you, but in contrast to the pepper, encrypting the hash allows to exchange the key, should this be necessary.

martinstoeckli
  • 5,149
  • 2
  • 27
  • 32
1

Remember that clever "brute force + dictionary" attacks rely on being able to try millions of guesses a second. Properly implemented bcrypt / PBKDF2 / scrypt will require several tenths of a second per guess, thus making brute force impractical on a large scale.

The Ars Technica article makes it clear in the first page that these attacks are being performed against unsalted MD5 hashes.

So if you want to protect against these attacks, choosing a high iteration count for your key derivation function is more important than any clever changes to the password or hash.

Rory Alsop
  • 61,367
  • 12
  • 115
  • 320
scuzzy-delta
  • 9,303
  • 3
  • 33
  • 54
  • 2
    What are you talking about?! How does this answer the question? – Adi Oct 17 '13 at 16:40
  • 1
    Attacks based on pattern guessing as described in the linked article are always demonstrated in environments where millions of guesses per second can be made. My point is that you can make better security gains by limiting guesses per second instead of any attempts to obscure the patterns. – scuzzy-delta Oct 17 '13 at 16:56
  • Great points. Write a blog post about them. However, they don't even attempt to answer the question. – Adi Oct 17 '13 at 17:30
  • @Adnan - I actually think this addresses it from a different angle. This is specifically the type of attack I was thinking about, and while it doesn't directly answer the *security* aspect of the question, it does address the concern that was behind it. +1 for that. – Bobson Oct 17 '13 at 20:36