How does Salt work in the CreateHash Method?

Topics: Cryptography Application Block
May 15, 2007 at 11:56 AM
Hi, I'm working on some code which uses the CreateHash method of the Cryptography Block. In the Web.Config, I've got salt enabled. However the Cryptographer.CreateHash method doesn't have a Salt parameter. Neither does the Compare hash method.

In the past somewhere else using methods in the main .net framework, I recall generating a salt string and then storing it in database, and needing to use it again when validating the hash.

However in the Cryptography Application Block theres no parameter for passing in a salt either at create or compare. So feeling a bit baffled by this at present, Does the Application Block generate its own Salt - if so, then dont I need to have the salt present when I do the compare?

Have googled on this but got nowhere. Appreciate if someone can help "pass the salt" ;-)
May 15, 2007 at 1:58 PM
hi Mickey -

The salt is generated and maintained in configuration. If you add a HashProvider that supports salt (HMACSHA), the configuration tool wil prompt you to generate the key (salt) and it will be stored in an encrypted file on disk (using DPAPI).

If you create an instance of this hashprovider from configuration it already knows about the salt and you basically dont need to worry about that anymore :-)

(you can export it by clicking on the elispes in the "key" property of such a hashprovider)
May 15, 2007 at 3:23 PM
Hi Olaf,

Thank you that helps move it bit forward.

I used the configuration tool. The file generated has the key saltEnabled="true", and uses System.Security.Cryptography.SHA1Managed but the tool never asked me about salt.

Should it have asked me for a Salt?

This is for a service that will sit on two web servers. So do I have to copy the salt file across? Sorry but when you say the elispes in the key property, where do I access that? Do I need to do anything special to store in the other server e.g to handle the DPAPI?
May 15, 2007 at 3:43 PM
Mickey - apologies, my previous answer was confusing and incorred. it applied to key management for keyed hashproviders.

anyhow; if salt is enabled on a HashProvider, the provider will generate a random sequence of bytes, that will be added to the hash. If you compare a hashed value with a unhashed value, the salt will be extracted from the hashed value and used to hash the unhashed value, prior to comparison.

hopefully that made more sense :-)

still, same rule applies: you do not have to worry about this, it's taken care of inside the provider :-).

and no, in order to use this there is no involvement of DPAPI.
May 16, 2007 at 8:02 AM
Edited May 16, 2007 at 8:38 AM
Hi Olaf,

No worries, thanks for the further explanation. I'm sorry but I am still having difficulty with understanding how this works.

My problem is that my understanding of the way that Salt works is that you add a small bit of random data into the hashing algorithm, but then you keep that salt with you, and you need to use the salt again later when it comes to compare the hashed data with a unhashed value.

The whole point of using a Salt is so that anybody else cannot simply use the same hashing algorithm to work out your value.

If as you are saying, the provider supplies its own salt - which it then "stores" in the hashed value, then anybody else using the Enterprise Library will be able to decode our hashed values. ie their Enterprise Library will "extract" the salt from the hashed value and then work out the value, once they guess which algorithm is being used. So if correct then that would be a very poor and unsatisfactory solution. Are you sure that this is how it is working - because it doesnt sound secure?

The only other thing I can think is that if the provider generates its Salt using say some kind of machine key from our environment for example, but then I need to understand how it does that so that I can make sure that the provider will generate the same Salt value on both web servers. (We have two web servers and the requests hashed on one and sent to the client, may later get returned to the other server).

(In our case we send a ID to the client machine, and in order to ensure that the ID is not tampered with, we also send a Hash of the ID to the client, both are querystring parameters in a single hyperlink. So if the user clicks on the link, then we check by making a Hash of the ID that it matches the Hash of the ID in the hyperlink. So its important to us to be able to make this hash using a Salt, so that somebody cannot simply change the ID and work out a Hash of the changed ID and add it in the hyperlink and then click on it - because if they could do this then it would look genuine to us. Thats why the Salt issue is important to us)

May 16, 2007 at 10:50 AM
As for decoding as hash-value. this cannot be done. after creating a hash there should be no way to reverse this into the original value.
However, what you can do is compare an unhashed-value with a hashed-value by putting it through the same algorithm and comparing the output.

The salt plays the role of appending some random data to to input, making sure that two different hashed representations of the same value result in a different hashed value.

so, given your example, someone that has the hashed value, needs to figure out the original value first, figure out the hash algorithm, the number of bytes that is stored as salt (and the end of the computed hash) and then do a comparison by putting the origanal and salt together, then running it through the hash algorithm.

you can use a specific type of hash algorithm, a KeyedHashProvider (as described on my first reply) to create the hash using an additional key (that is stored somewhere secure). These keys are protected using DPAPI and this means you'll have to export/import the key to your webservers (using the configuration tool).
May 16, 2007 at 12:51 PM
We send the original value and the hashed value to the clients browser in a link. ie href="somedomain.com?ID="15"&HashID="2225"

Then when they click on the link we want to check that they have not tampered with the original ID value, so we make a second hash and compare with the original hash value.

So in our case somone already has the original value and the hash. If they change ID to ID2, then as they dont know what Salt we use, then their HashID2 will not match the HashID2 that we will make, and so we will know that the ID has been tampered with.

Thats why i've been trying to find out how to specify a Salt value, or trying to find out if the Salt value is a value unique to us from our configuration. If I can specify a salt value OR if I know that the Salt value is unique to us, then I dont need to spend the time to change to other algorithms especially as it is hard to test our live environment as we dont have two webservers in integration, but have two in live.