Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Encrypting user name and password
Message
General information
Forum:
Visual FoxPro
Category:
Other
Environment versions
Visual FoxPro:
VFP 9 SP2
Miscellaneous
Thread ID:
01635942
Message ID:
01636072
Views:
88
As Sergey pointed out the best practice is to one-way hash passwords and store that in the database. In order to check for a valid password you then hash the user's input and see if it matches the stored password in the database.

In addition to simply hashing you usually want to 'salt' the hash with a unique value based on the data you're hashing. Usually that's some unique ID along combined with some static text which further obfuscates the hash and makes it different for even data that is very similar.

If you use any West Wind tools there's a wwEncryption class that has a salted hash generation routine. I use this both in my Fox and .NET applications and it works very well.

Here's the documentation for the class (which is a wrapper around the .NET Encryption APIs with the salting added on top):

Class wwEncryption

The specific function to use there is ComputeHash().

There's nothing fancy about this code BTW - it's just a little bit of .NET code called from FoxPro. Here's the .NET code for the ComputeHash() function:
/// <summary>
/// Generates a hash for the given plain text value and returns a
/// base64-encoded result. Before the hash is computed, a random salt
/// is generated and appended to the plain text. This salt is stored at
/// the end of the hash value, so it can be used later for hash
/// verification.
/// </summary>
/// <param name="plainText">
/// Plaintext value to be hashed. 
/// </param>
/// <param name="hashAlgorithm">
/// Name of the hash algorithm. Allowed values are: "MD5", "SHA1",
/// "SHA256", "SHA384", and "SHA512" (if any other value is specified
/// MD5 hashing algorithm will be used). This value is case-insensitive.
/// </param>
/// <param name="saltBytes">
/// Salt bytes. This parameter can be null, in which case a random salt
/// value will be generated.
/// </param>
/// <returns>
/// Hash value formatted as a base64-encoded string.
/// </returns>
public static string ComputeHash(string plainText,
                                 string hashAlgorithm,
                                 byte[] saltBytes)
{
    if (plainText == null)
        return null;

    // If salt is not specified, generate it on the fly.
    if (saltBytes == null)
        saltBytes = SaltBytes;

    // Convert plain text into a byte array.
    byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

    // Allocate array, which will hold plain text and salt.
    byte[] plainTextWithSaltBytes =
            new byte[plainTextBytes.Length + saltBytes.Length];

    // Copy plain text bytes into resulting array.
    for (int i = 0; i < plainTextBytes.Length; i++)
        plainTextWithSaltBytes[i] = plainTextBytes[i];

    // Append salt bytes to the resulting array.
    for (int i = 0; i < saltBytes.Length; i++)
        plainTextWithSaltBytes[plainTextBytes.Length + i] = saltBytes[i];
    
    HashAlgorithm hash;

    // Make sure hashing algorithm name is specified.
    if (hashAlgorithm == null)
        hashAlgorithm = "";

    // Initialize appropriate hashing algorithm class.
    switch (hashAlgorithm.ToUpper())
    {
        case "SHA1":
            hash = new SHA1Managed();
            break;

        case "SHA256":
            hash = new SHA256Managed();
            break;

        case "SHA384":
            hash = new SHA384Managed();
            break;

        case "SHA512":
            hash = new SHA512Managed();
            break;                
        default:
            // default to MD5
            hash = new MD5CryptoServiceProvider();
            break;
    }

    // Compute hash value of our plain text with appended salt.
    byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes);

    
    return Convert.ToBase64String(hashBytes);
}
Hope this helps,

+++ Rick ---

>>Hi,
>>
>>I am designing a new module where each user would have to be assigned a user name/id and password. This information will be stored in a SQL Server table. I have two questions:
>>1. Is it acceptable practice to store the user name/id un-encrypted (readable by anyone)?
>>2. What method of encrypting the password would you recommend (does not have to be Super Secure) that later can be used by another (e.g. .NET) application?
>>
>>TIA
>
>
>Store hash of the password. this way nobody can decrypt it including you
+++ Rick ---

West Wind Technologies
Maui, Hawaii

west-wind.com/
West Wind Message Board
Rick's Web Log
Markdown Monster
---
Making waves on the Web

Where do you want to surf today?
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform