No sane system follows the "store the data in multiple places" design; you'd need to pull it all back together to validate the password anyway, and a breach is extremely likely to compromise a system that can do exactly that.
Similarly, creating a salt from a calculation rather than, say, taking 128 random bits, is not going to help, nor is depending on the secrecy of the source code ever a prudent choice. It will certainly produce less entropy than the latter, will not produce a different salt across password changes, and is just very, very hacky.
I agree with sk5t. You can't count on the source to stay secure in a breach. It only adds unnecessary complexity without adding security. You are simply adding length to the password with your own key lengthening algorithm using values that are still in the database or source. You might think your clever (UserName + PassWord + User ID + CreationDate + ...) function adds strength because the current cracking tool doesn't have your clever function. This clever function can be easily added to the cracking tools thus rendering your clever function useless. What you failed to do was actually add a secret that you can guarantee to keep secret even when the database and source are breached. This is why a secure hardware device like the YubiHSM is recommended as the secret is never revealed even in a breach.
A calculated value means you need source to figure it out. Only PHP and JS/Node scripters assume that their source isn't safe in an attack. The rest of us assume that our compiled code is safe.
(Over generalization, but if people can get your source code basically there is zero you can do to keep them out)
Storing data in more than one store is a best practice.
Your random 128 bits have to be stored somewhere. That means an attacker needs only the database, not the source. In any large scale environment you likely have multiple machines. When a machine gets taken out of service at your hosting provider your database might still be on it when it hits the dumpster. If your source code is on another machine it doesn't matter.
The same is true of the Private User Data and the passwords. two locations means you need two breaches to do anything.
>A calculated value means you need source to figure it out.
As I mentioned in my other post, it really doesn't. Using a calculated value means that the entropy of your salt is only as high as the values used to calculate it.
>Only PHP and JS/Node scripters assume that their source isn't safe in an attack.
So, the vast majority of websites.
>The rest of us assume that our compiled code is safe.
Why would you assume that?
>if people can get your source code basically there is zero you can do to keep them out
If people have your source code, and your passwords are stored properly, they aren't going to have any easier of a time cracking them.
>Your random 128 bits have to be stored somewhere. That means an attacker needs only the database, not the source.
The whole point of a salt is that it doesn't have to be secret.
The cracking community, unlike the bulk of the mainstream programming community, has not lost the art of disassembling executable code. Hiding source code provides negligible additional security.
It still confers a negligible advantage. If the attackers have gotten into your data server, why shouldn't they be able to get into your application server just as easily? All you're doing is slightly inconveniencing the attacker before they can derive your salt wholesale.
Always remember: a secure system is secure even if the attacker can see your source code. Any work you do based on assuming the opposite is a waste of time.
Really? How about because my database server could be something like DynamoDB that I don't own. Why would the execution and the Data server have the same vulnerabilities. The whole reason to have two servers is so that you can say. "The only thing that can talk to the database is a server on the 'Inside'", but injection attacks mean you could possibly exploit the data server with no access to the execution server.
Even so, you're proposing a very low entropy salt. If the attacker can crack one or two weak passwords, they can start limiting their search space immediately, and crack more passwords. As they gain more examples to work with, they will be able to work out how your salt is derived, and then they can start looking for salt collisions based only on the data that is stored in the clear.
At that point, your attacker has not only the ability to derive the salt and attack each password individually, but potentially the ability to generate rainbow tables for subsets of users with identical (or largely identical) derived salts.
The point is that at best, you're adding a term to the overall hardness of the attack. When you use something like bcrypt, you are multiplying the hardness of the attack. There is no comparison between what you've proposed with MD5 or SHA-1 and simply using bcrypt on a random salt, even if the latter has your source code in the latter but not the former.
No sane system follows the "store the data in multiple places" design; you'd need to pull it all back together to validate the password anyway, and a breach is extremely likely to compromise a system that can do exactly that.
Similarly, creating a salt from a calculation rather than, say, taking 128 random bits, is not going to help, nor is depending on the secrecy of the source code ever a prudent choice. It will certainly produce less entropy than the latter, will not produce a different salt across password changes, and is just very, very hacky.