How can I encrypt passwords?

Posted on 2001-06-22
Medium Priority
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
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 400 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 Blowfish_PP.pm 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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

I have helped a lot of people on EE with their coding sources and have enjoyed near about every minute of it. Sometimes it can get a little tedious but it is always a challenge and the one thing that I always say is:   The Exchange of informatio…
I would like to start this tip/trick by saying Thank You, to all who said that this could not be done, as it forced me to make sure that it could be accomplished. :) To start, I want to make sure everyone understands the importance of utilizing p…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…
Suggested Courses

777 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