1

I'm developing a personal web framework, nothing internetty, and probably not even anything that will ever go on my personal LAN. And looking for password advice people seem to only recommend those libraries in the title. I'm doing this to learn security from a development perspective, and again, I'm aware this isn't best practice I want to learn by implementing it myself (and hassling the community with relentless questions).

Currently my routine does 4096 rounds of salted SHA512 (a number plucked out of thin air - I'll concede thats one thing they probably have sorted) like so:

string randomdatabasesalt = "whateverdatabasesalt"  
user = "username"
string password = "whateverpassword"  
for (int i = 0; i < 4096; i++)  
{  
  password = SHA512(user + randomdatabasesalt + password);  
}   
store (user, password);  

Now if I feel the need at a later date I can add more rounds to everyones hash (pre-breach of course) and can strengthen it without anyone needing to reset passwords, all reasonably easily. Or if SHA2 becomes completely broken with regards to cracking speed, I can rehash those hashes and add it into the routine with noone being any the wiser though that may be an undesirable waste of cycles. So whats wrong with this approach - other than the random rather than computed selection of rounds? Is it just the lack of peer review or do the aforementioned libraries do something I'm not taking into account?

Secondary question, would adding the salts each pass somehow weaken the hashing? Is it better to salt just the initial hash then loop through? Example:

string password = "whateverpassword" 
password = SHA512(user + randomdatabasesalt + password); 
for (int i = 0; i < 4095; i++)  
{  
    password = SHA512(password);
}   
store (user, password);  
user2867314
  • 610
  • 3
  • 12
  • Do you mean to tell me that your way of securing your passwords is more complex than [this](https://gist.github.com/cetanu/9afd1e3b884de1dd7bf1)? http://en.wikipedia.org/wiki/PBKDF2#Key_derivation_process – Vasili Syrakis Jun 23 '14 at 06:18
  • Absolutely not, but more complex doesn't necessarily mean better and in many cases results i the complete opposite (clearly it does mean better in this case, though). It was a simple function that appeared to tick all the boxes for secure password storage, so I wanted to know the flaws. – user2867314 Jun 23 '14 at 09:34

1 Answers1

8

Well, it is a mixture of "no peer review" and "something you do bad". The thing you are (apparently) doing poorly is your salt selection: you call it "randomdatabasesalt", which hints at the idea that you would use the same salt value for several hashes, if you had to store several password hashes (e.g. because your framework has several users). This is a sin: it voids most of the reason why you would use a salt in the first place. Salts should be per-instance: each user should have his own salt, and the salt must be changed when the user changes his password.

As for the rest: anybody can create a cryptographic scheme that he cannot break. The hard part is to create a scheme that nobody else can break it either. The really hard part is to make sure that nobody else can break it (because we want security, but we also want to sleep at night).

Cryptographers thus rely on peer review and slow-paced development. When they want to design a new function, they organize a competition in which people are encouraged to submit candidates, complete with specification, test vectors and reference implementations; and then they spend some time (years) to try to break each other's creations. Survivors are then deemed "probably secure". This is what was done for AES and SHA-3, for instance. And, right on cue, there is an ongoing competition for password hashing functions.

This presentation is a nice introduction on password hashing, and lists some features that good password hashing functions should have. Have also a look at that answer.

(One way of designing cryptosystems which does NOT work is a fast comment-modify cycle. It usually happens as a dialogue between a wannabe designer, and an amicable and knowledgeable cryptographer. The designer, full of zeal, will submit an endless stream of minor variants of his scheme, each adding some random construct to answer to the last comment from the cryptographer. This always ends up with the cryptographer being fed up and ceasing to respond; the designer then claims victory and writes a colourful Web page, and then fails to become rich overnight when the rest of the World does not acknowledge the genius of the new algorithm.)

Thomas Pornin
  • 322,884
  • 58
  • 787
  • 955
  • 2
    Also, the SHA-family of hashes are *very* fast to compute in dedicated hardware, and not so fast in general purpose CPUs. One design criteria of a slow-hash is to minimize any possible advantage of an attacker over a defender. SHA-512 is a poor choice for that. – Stephen Touset Jun 20 '14 at 18:01
  • 2
    `scrypt` has memory-hardness as well (distinguishing it from `bcrypt` and `PBKDF2`). If each hash requires 16MB to compute, an attacker with a 2,560-core GPU would require over 40GB of memory on the card to fully utilize every core – typical graphics cards of this caliber only have 4–8GB of memory. You can forget about FPGAs or ASICs. Iterated SHA, on the other hand, can be done essentially entirely in GPU registers. – Stephen Touset Jun 20 '14 at 18:08
  • well yes but the user is mixed in with the salt here, creating something while not truly random is at least a per user arrangement, so it would take a massive information disclosure to release both the username and password salts, or is this irrelevant? And again, I'm not trying to design secure password storage here, just fully understand what is wrong with it. – user2867314 Jun 20 '14 at 20:06
  • Of course I could come up with a random salt-but again, I'm looking for the flaws here, so effectively the salt is "username"+"saltForEntireDatabase" so two combinations of bad salts as stated by your (incredibly helpful) post that comes up with something somewhat unique;per user at least. Isnt a rainbow table only going to help if both are known in advance? By the time my db is breached to get said salt there **SEEMS TO ME** like nothing I can do but rely on the slowness of the algorithm. But yes. salt doesnt change on passchange! Thanks both though. @StephenTouset Your point is spot on. – user2867314 Jun 20 '14 at 20:50
  • @StephenTouset Doesn't `bcrypt` require 4 KiB of fast memory, making it a bit more expensive on ASICs since you can't perform the calculation efficiently using only registers? – forest Aug 15 '18 at 00:33