|
A one-way hash function is a cryptographic
algorithm that turns an arbitrary-length input into a fixed-length binary value,
and this transformation is one-way, that is,
given a hash value it is statistically infeasible to
re-create a document that would produce this value.
There are three widely used hash algorithms: MD4, MD5, and SHA. MD4 and MD5
produce 128-bit hashes, and SHA a 160-bit hash.
Although the main purpose of hash functions in cryptography is to produce digital
signatures, they can also be used to protect passwords in a user database. The idea is
to store the hash values of passwords instead of the passwords themselves. To validate
user credentials, the hash function is applied to the password submitted
by a user and the resulting value is compared with the hashed password stored in the database.
If the hashes match the user is authenticated. This way, even is the user database falls into
the wrong hands it will be hard for the intruder to recover the actual user passwords.
With AspEncrypt, a hash function is computed in three steps:
1. Create a CryptoHash object.
2. Add a text string or file to it. This step may be repeated several times.
3. Retrieve the result in a desired format.
<%
Set CM = Server.CreateObject("Persits.CryptoManager")
Set Context = CM.OpenContext("", True)
Set Hash = Context.CreateHash
Hash.AddText "some text"
Response.Write Hash.Value.Hex
%>
|
The CreateHash method accepts an optional HashAlgorithm argument. It is calgSHA by default.
The Hash.Value property returns a CryptoBlob object containing the computed hash value.
This blob object can be queried using the Hex, Base64 or Binary properties as described in previous sections.
Even a hash-encrypted password database is not entirely secure. A hacker
can compile a list of, say, 1,000,000 most commonly used
passwords and compute a hash function from all of them. He can then get hold of your
user account database and compare the hashed passwords in the database with
his own list to see what matches. This is a "Dictionary Attack"
and it can be very successful.
To make the dictionary attack more difficult, salt is used. Salt is
a random string that is concatenated with passwords before being operated on
by the hash function. The salt value is then stored in the user database
together with the result of the hash function. Using salt makes dictionary attacks
practically impossible as a hacker would have to compute the hashes for all possible
salt values. However, salt does not help make attacks on individual passwords any harder,
therefore it is important to use passwords that are hard to guess.
The sample MS Access database shipped with the product contains the table
Users which has three fields: Username, Password and Salt. The following ASP code
(also found in the file Samples\Passwords\AddUser.asp of the installation)
allows you to add a user account to the Users table. Salt is calculated
by concatenating together 10 random characters between 'A' and 'Z'.
<HTML>
<BODY>
<%
If Request("Create") <> "" Then
If Request("Password") = Request("Password2") Then
' Generate random salt (10 characters)
Randomize
Salt = ""
For i = 1 to 10
Salt = Salt & chr(int(Rnd * 26) + 65) '65 is ASCII for "A"
Next
' Calculate Hash of Password + Salt
Set CM = Server.CreateObject("Persits.CryptoManager")
Set Context = CM.OpenContext("", True)
Set Hash = Context.CreateHash
Hash.AddText Request("Password") & Salt
HashValue = Hash.Value.Hex
' Save username, hashed value and salt in the database
set Conn = Server.CreateObject("adodb.connection")
Conn.Open "DSN=AspEncrypt;UID=;PWD=;"
SQL = "insert into Users(Username, Password, Salt) _
values('" & Request("Username") & "','" & HashValue & "','" & Salt & "')"
Conn.Execute SQL
Response.Write "Account was successfully created."
Else
Response.Write "Password was not correctly confirmed."
End If
End If
%>
<FORM ACTION="AddUser.asp" METHOD="POST">
Username:<INPUT TYPE="TEXT" NAME="Username">
Password:<INPUT TYPE="PASSWORD" NAME="Password">
Confirm Password:<INPUT TYPE="PASSWORD" NAME="Password2">
<INPUT TYPE="Submit" NAME="Create" VALUE="Create Account">
</FORM>
</BODY>
</HTML>
|
The following code snipped (also found in the file Samples\Passwords\Validate.asp) validates
a submitted username/password pair against the Users database.
<HTML>
<BODY>
<%
If Request("ValidateIt") <> "" Then
' Obtain user record (hashed value and salt) by username
set rs = Server.CreateObject("adodb.recordset")
SQL = "select password, salt from Users _
where Username = '" & Request("Username") & "'"
rs.Open SQL, "DSN=AspEncrypt;UID=;PWD=;"
If Not rs.EOF Then
HashValue = rs("Password")
Salt = rs("Salt")
' Calculate Hash of specified password + Salt from DB
Set CM = Server.CreateObject("Persits.CryptoManager")
Set Context = CM.OpenContext("", True)
Set Hash = Context.CreateHash
Hash.AddText Request("Password") & Salt
HashValue2 = Hash.Value.Hex
If HashValue = HashValue2 Then
Response.Write "Account was successfully validated."
Else
Response.Write "Invalid Password."
End If
Else
Response.Write "User not found."
End If
End If
%>
<FORM ACTION="Validate.asp" METHOD="POST">
Username:<INPUT TYPE="TEXT" NAME="Username">
Password:<INPUT TYPE="PASSWORD" NAME="Password">
<INPUT TYPE="Submit" NAME="ValidateIt" VALUE="Validate Account">
</FORM>
</BODY>
</HTML>
|
|
|
|
|
|