How can I encrypt passwords?

Posted on 2001-06-22
Last Modified: 2009-04-14
I need to encrypt the passwords that the users enter before storing them in a database, how can I do that in asp?

Thank you

Question by:m02759
  • 2
  • 2
LVL 18

Expert Comment

ID: 6220583
With a Perl utility... ;-)

(well, at least that's how I do it...)

The first issue you will encounter is not just encoding the string, but decoding the returning string.  There are a few different ways, but it would take volumes of material to cover the whole mess...  this is an issue that can take a lot of time and reading.  Lets see what the experts say.

Accepted Solution

epeele earned 100 total points
ID: 6220629
Password Encryption
The Users table contains fields for a randomly generated string (called a salt) and the encrypted password.

To encrypt a password, two basic functions are defined in the 'common.asp' file. One generates a random salt string and the other encrypts a character string using the Secure Hash algorithm (see FIPS PUB 180-1 for details on this hash algorithm).

The purpose of the salt is to prevent "dictionary attacks". Users tend to use common words or phrases for passwords so it's possible to take a number of common terms, hash them using the same algorithm and compare these to the encrypted passwords stored in the database, looking for a match.

A salt is random string of characters. By adding it to the user's password you can be almost certain that the password will no longer match any common term. In other words, it makes an easy-to-guess password very difficult to guess.

The salt value is stored in the database so that it can be used anytime password checking is needed. The user does not have to remember or even know the salt.

The hash function performs several mathematical calculations using the ASCII values of the characters in the input string. These calculations are one-way, meaning that it's impossible to take the hash value, undo the calculations and derive the original input.

Due to the arithmetic operations required, the actual hash function is written in JScript rather than VBScript. To allow this mixing of scripting languages, the JScript code needed is located at the end of the 'common.asp' file within SCRIPT tags.

<% '... VBScript code...

   function Hash(str)

     'Call the JScript function to calculate
     'the SHA-1 message digest for the string.

     Hash = SecureHash(str)
   end function
   '... %>

   // ...JScript code...

   function SecureHash(s) {

     // ...calculate and return hash value...
   // ...

The JScript code includes the SecureHash() function itself along with a few helper functions it uses.

The code is below:

<%@ Language=VBScript %>
' CreateSalt(): Returns an eight-character random salt string. Used for
' generating the hash for passwords.

function CreateSalt()

  dim i, n, chars

  CreateSalt = ""
  chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  for i = 1 to 8
    n = Int(Len(chars) * Rnd()) + 1
    CreateSalt = CreateSalt & Mid(chars, n, 1)

end function

' Hash(str): Returns a 40-character hash value for the given string. Used
' for storing passwords.

function Hash(str)

  'Call the JScript function to calculate the SHA-1 message digest for the

  Hash = SecureHash(str)

end function

' ErrorMessage(msg): Outputs 'msg' in the error style.

sub ErrorMessage(msg)

  Response.Write("<br><span class=""error"">" & msg & "</span>")

end sub

' InfoMessage(msg): Outputs 'msg' in the info style.

sub InfoMessage(msg)

  Response.Write("<br><span class=""info"">" & msg & "</span>")

end sub %>


// Note change in scripting language.

 * SecureHash(s): Calculates the message digest for the given string using *
 * the SHA-1 algorithm.                                                    *

function SecureHash(s) {

  var bitLen, n, w;
  var k, buffer, f;
  var h0, h1, h2, h3, h4;
  var a, b, c, d, e, temp;
  var i, j;

  // Pad the input message per the SHA-1 specification.

  bitLen = s.length * 8;
  n = 512 - (bitLen % 512);
  if (n <= 65)
    n += 512;
  s += String.fromCharCode(0x80);
  n -= 8;
  for (i = 0; i < n / 8; i++)
    s += String.fromCharCode(0x00);

  // Convert padded message to an array of 32-bit integers, note conversion
  // to little endian.

  w = new Array();
  for (i = 0; i < s.length; i += 4) {
    n = 0;
    for (j = 0; j < 4; j++)
      n = (n << 8) + s.charCodeAt(i + j);
    w[w.length] = n;

  // Set last word to the original bit length of the message.

  w[w.length - 1] = bitLen;

  // Initialize hash values, constants and buffer.

  h0 = 0x67452301;
  h1 = 0xEFCDAB89;
  h2 = 0x98BADCFE;
  h3 = 0x10325476;
  h4 = 0xC3D2E1F0;

  k = new Array(80);
  for (i = 0; i < 80; i++)
   if (i < 20)
     k[i] = 0x5A827999;
   else if (i < 40)
     k[i] = 0x6ED9EBA1;
   else if (i < 60)
     k[i] = 0x8F1BBCDC;
     k[i] = 0xCA62C1D6;

  buffer = new Array(80);

  // Process word array in 512-bit (16-word) blocks.

  n = w.length / 16;
  for (i = 0; i < n; i ++) {

    // Initialize 80-word buffer using the current block.

    for (j = 0; j < 80; j++)
      if (j < 16)
        buffer[j] = w[i * 16 + j];
        buffer[j] = rol(buffer[j - 3] ^ buffer[j - 8] ^ buffer[j - 14] ^
                        buffer[j - 16], 1);

    a = h0; b = h1; c = h2; d = h3; e = h4;

    // Hash the block.

    for (j = 0; j < 80; j++) {
      temp = rol(a, 5);
      if (j < 20)
        f = (b & c) | ((~b) & d);
      else if (j < 40)
        f = b ^ c ^ d;
      else if (j < 60)
        f = (b & c) | (b & d) | (c & d);
        f = b ^ c ^ d;
      temp = add(temp, f);
      temp = add(temp, e);
      temp = add(temp, buffer[j]);
      temp = add(temp, k[j]);
      e = d; d = c; c = rol(b, 30); b = a; a = temp;

    // Update hash values.

    h0 = add(h0, a);
    h1 = add(h1, b);
    h2 = add(h2, c);
    h3 = add(h3, d);
    h4 = add(h4, e);

  // Format hash values and return as message digest.

  return hex(h0) + hex(h1) + hex(h2) + hex(h3) + hex(h4);

// Helper functions for the Secure Hash function.

function rol(x, n) {

  // Left circular shift for a 32-bit integer.

  return (x << n) | (x >>> (32 - n));

function add(x, y) {

  // Add two 32-bit integers, wrapping at 2^32.

  return ((x & 0x7FFFFFFF) + (y & 0x7FFFFFFF)) ^
          (x & 0x80000000) ^ (y & 0x80000000)

function hex(n) {

  var hexDigits = "0123456789ABCDEF";
  var i, s;

  // Format a 32-bit integer as a hexadecimal string.

  s = "";
  for (i = 7; i >= 0; i--)
    s += hexDigits.charAt((n >> (i * 4)) & 0x0F);

  return s;


Sample Usage:

<!-- #include file="common.ssp" -->
<!-- #include file="header.asp" -->

 'Open the database

 call OpenDB()

'Get any form data.

 username = Request("username")
 password = Request("password")

   if Request.Cookies("Cookie") = "" then
     call ErrorMessage("You must use a browser that supports cookies and<br>" _
       & "have them enabled in order to access this site.")

     'Check input.

     if username = "" then
       call ErrorMessage("Please select a username.")
     elseif password = "" then
       call ErrorMessage("Please enter your password.")

       'Verify the password and redirect to default page if correct.
       sql = "select * from Users" _
          & " where Username = '" & username & "'"
       set rs = DbConn.Execute(sql)
         if rs.EOF and rs.BOF then
           call ErrorMessage("User '" & username & "' not found.")
         elseif Hash(rs.Fields("Salt").Value & password) <> rs.Fields("Password").Value then
           call ErrorMessage("Incorrect password, please reenter.")
           Session("Username") = rs.Fields("Username").Value
         end if
     end if

 end if


LVL 18

Expert Comment

ID: 6220644

excatly 299 lines of VERY good information!

The issue of encrypting, as I mentioned will fill volumes... how much time do you have?

Here is a very nice Perl solution, do you know Perl?  Plus it's VERY secure... (nothing is 100%);

sub bfInit() {
    unless ($Crypt::Blowfish_PP::VERSION) {
        require Crypt::Blowfish_PP;   ### load module
        print "Crypt::Blowfish_PP $Crypt::Blowfish_PP::VERSION Loaded\n";
    my $key = "MYSECRET";  ### ;-)
    return Crypt::Blowfish_PP->new($key); ### return object reference

sub bfEncrypt() {
    ### takes a string and returns the encrypted string
    my $bf  = bfInit() or return 0; ### init returns new Blowfish_PP object
    my $val = shift(); ### value to be encrypted
    # OK, take the string to be encoded, unpack it into an array of strings
    # with 8 bytes each, encrypt each element of the resulting array
    # and join the all encrypted elements together into one final string

sub bfDecrypt() {
    ### takes an encryped sting and returns the decrypted value
    my $bf  = bfInit() or return 0; ### init returns new Blowfish_PP object
    my $val = shift(); ### value to be decrypted
    # OK, take the string to be decoded, unpack it into an array of strings
    # with 8 bytes each, decrypt each element of the resulting array
    # and join all decrypted elements together into the origin string
    $val =
    $val =~ s/\x00//g; ### remove binary zeroes and end of string
    return $val;


Author Comment

ID: 6220654

I was expecting a referral to some utility or so! But boy! you've covered it all! I can't thank you enough!
Thanks to mgfranz too! But I've never used perl before!


Expert Comment

ID: 6224235
You're welcome, m02759.  Thanks for the grade!  mgfranz, nice solution too.  :)

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
How to solve this equation 3 52
Update function to validate checkbox is checked 4 65
SQL Filter Question 8 79
JQuery to parse xml string and get element by id 4 23
Hello, all! I just recently started using Microsoft's IIS 7.5 within Windows 7, as I just downloaded and installed the 90 day trial of Windows 7. (Got to love Microsoft for allowing 90 days) The main reason for downloading and testing Windows 7 is t…
This demonstration started out as a follow up to some recently posted questions on the subject of logging in: and…
Hi friends,  in this video  I'll show you how new windows 10 user can learn the using of windows 10. Thank you.
Learn how to create flexible layouts using relative units in CSS.  New relative units added in CSS3 include vw(viewports width), vh(viewports height), vmin(minimum of viewports height and width), and vmax (maximum of viewports height and width).

920 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now