Reducing Vulnerability: Salting a Hash
In culinary circles, salt is used as a preservative
and a flavor enhancer. In the days before refrigeration meat was
heavily salted for extended storage. The salt slowed the deterioration
of the meat and prevented mold and bacteria from contaminating it. This
protected the integrity of the meat so that its quality could be
assured for a reasonable length of time.
Salt in cryptography has a similar effect. A one-way
encrypted hash value is vulnerable to dictionary and rainbow table
attacks; but adding a salt to the plain text, before it is encrypted,
results in a hash value that is very resilient to these attacks.
Salting renders the underlying plain text more complex, and breaks
expected patterns that can be anticipated by the attacker.
For example, an attacker who is executing a
dictionary attack against a table that contains unsalted hash values of
Social Security Numbers will anticipate that the patterns of the plain
text will be "000-00-0000" or "000000000". This known pattern provides
the attacker with a finite combination of approximately one billion (109)
possible values. However, if the Social Security Number is salted with
a seven character alphanumeric value, for example, then the possible
combinations for the plain text values skyrockets to over seventy eight
quintillion (78 x 1018). Therefore, salting is a highly effective way of strengthening one-way encryption.
In the HomeLending database we will create a scalar-valued user defined function, called GetHashSalt, which is designed to return a seven character value, which will be used as the salt portion of a one-way encryption process.
Scalar-valued user defined function:
... is a function in which the value that is returned from its execution is a single value.
Listing 1 shows the script to create our GetHashSalt
function. We will offer six variations of salt values designated with
the values "L01" through "L06". These variations will provide a deeper
level of protection to items that are salted throughout our database.
These are the values that will be passed through the @Type argument of this user defined function.
Inclusion of the WITHENCRYPTION option
prevents the revelation of these salt values by viewing the definition
of the user defined function, as well as preventing its modification.
This renders the code of the user defined function invisible through
catalog views, unencrypted backup files and through SSMS.
With this user defined function, we can salt our
plain text values before they are encrypted. The process of doing this
involves the following steps:
Call the GetHashSalt user defined function and assign it to a variable.
Concatenate the variable to the plain text of the data that is to be encrypted.
Place the resulting concatenated value in the plain text argument of the Hashbytes function.
For example, an original plain text of "555-37-0143"
and a salt value being "HYz5#4555", the resulting concatenated value
will be "HYz5#45555-370143". Using the "SHA1" algorithm, the resulting
salted hash value will be 0xD544F25AC44F6CBC108DA211D2A48990A343359C.
Listing 2 will grant EXECUTE permissions on the GetHashSalt UDF to the Sensitive_high and Sensitive_meduim database roles.
Specific examples of the application of a salt, with the HomeLending database, will be illustrated in the following one-way encryption demonstration.