I'm not entirely sure what's going on above, so let me explain hashes a bit, this has been done before, and there are sources, but I'll have a go anyway! It was new to us all once!
If we have a function, call it f
and let it be our hash function, it takes every possible input to just a finite number of outputs, this is why it can't be reversed, this is called a surjective function http://en.wikipedia.org/wiki/Surjection see there for more. Like f(x)=x^2
if f(x)=4
we don't actually know what x is (we happen to know it can be either 2 or -2 though)
The hash is of a different order though because an infinite number of (theoretical, computers can't handle the longest of the set of all strings, it is too large!) inputs to a finite number of outputs.
If I know it's a pin-number suppose, suppose your pin number is P
I know f(P)=h
, and P is 1 of 10,000 values, 0000 to 9999 inclusive. So I can just do 10k hashes (worst case) and get your pin.
The salt is some random crap that's deterministically applied to the input, so suppose s(x)
salts x, it could be by putting the letter "k" between each letter of the input (this would be a crap salt though) but that way the output of s
only depends on x
, given the same input we get the same output.
Then you do f(s(x))
to get your hash, this way if I know the hash, but don't know the salt, I'd have to work out how you salted it first, if I did know the salt I'd have to know how you applied it, and so forth.
So suppose you did the simple salt above to passwords, so the common "password" becomes "pkakskskwkokrkd", and I have my "rainbow table" (a list of inputs and their hash values), I probably wont have (the salted form) in that table, but suppose I know the hash, and that you put ks between letters, I'd have to re-create my rainbow table using words but with ks in them and that'd take a lot of memory, a lot of time..... but then I can break all your passwords (because the salt was the same for all)
This is what your system means by "users salt", that way if I break the system with ks only one guy's stuff is cracked, I'd have to do it for everyone.
Now for some PHP code!
I recommend you use a sha512 salt, this gives a fixed 128 character-long (it's PHP, it'll end up in a database) output for any input.
$hash = hash("sha512",$data);
To salt it you can hash it several times, you can put a k between it, as long as it is 'deterministic' the same for a given input.
Lastly how it works:
If the bank has a salted hash of my pin number, they don't "break" it, to get my pin number to compare the number I entered with them, they salt and hash the pin number I just put in, and compare the value with the result in the database, if the hashes are the same, the pins entered are the same.
Hashes can collide but this is VERY rare, the "Avalanche Effect" was studied and made sure to be present (terminology?) in hashing algorithms, a similar input gives a wildly different output.
Hashes are only good for equality tests.