zoukankan      html  css  js  c++  java
  • How to Hash Data with Salt

    ///////////////////////////////////////////////////////////////////////////////
    // SAMPLE: Hashing data with salt using MD5 and several SHA algorithms.
    //
    // To run this sample, create a new Visual C# project using the Console
    // Application template and replace the contents of the Class1.cs file with
    // the code below.
    //
    // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
    // EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
    // WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
    // 
    // Copyright (C) 2002 Obviex(TM). All rights reserved.
    // 
    using System;
    using System.Text;
    using System.Security.Cryptography;
    
    /// <summary>
    /// This class generates and compares hashes using MD5, SHA1, SHA256, SHA384, 
    /// and SHA512 hashing algorithms. Before computing a hash, it appends a
    /// randomly generated salt to the plain text, and stores this salt appended
    /// to the result. To verify another plain text value against the given hash,
    /// this class will retrieve the salt value from the hash string and use it
    /// when computing a new hash of the plain text. Appending a salt value to
    /// the hash may not be the most efficient approach, so when using hashes in
    /// a real-life application, you may choose to store them separately. You may
    /// also opt to keep results as byte arrays instead of converting them into
    /// base64-encoded strings.
    /// </summary>
    public class SimpleHash
    {
        /// <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. The function does not check whether
        /// this parameter is null.
        /// </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 salt is not specified, generate it on the fly.
            if (saltBytes == null)
            {
                // Define min and max salt sizes.
                int minSaltSize = 4;
                int maxSaltSize = 8;
    
                // Generate a random number for the size of the salt.
                Random  random = new Random();
                int saltSize = random.Next(minSaltSize, maxSaltSize);
    
                // Allocate a byte array, which will hold the salt.
                saltBytes = new byte[saltSize];
    
                // Initialize a random number generator.
                RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    
                // Fill the salt with cryptographically strong byte values.
                rng.GetNonZeroBytes(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];
    
            // Because we support multiple hashing algorithms, we must define
            // hash object as a common (abstract) base class. We will specify the
            // actual hashing algorithm class later during object creation.
            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:
                    hash = new MD5CryptoServiceProvider();
                    break;
            }
            
            // Compute hash value of our plain text with appended salt.
            byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes);
            
            // Create array which will hold hash and original salt bytes.
            byte[] hashWithSaltBytes = new byte[hashBytes.Length + 
                                                saltBytes.Length];
            
            // Copy hash bytes into resulting array.
            for (int i=0; i < hashBytes.Length; i++)
                hashWithSaltBytes[i] = hashBytes[i];
                
            // Append salt bytes to the result.
            for (int i=0; i < saltBytes.Length; i++)
                hashWithSaltBytes[hashBytes.Length + i] = saltBytes[i];
                
            // Convert result into a base64-encoded string.
            string hashValue = Convert.ToBase64String(hashWithSaltBytes);
            
            // Return the result.
            return hashValue;
        }
    
        /// <summary>
        /// Compares a hash of the specified plain text value to a given hash
        /// value. Plain text is hashed with the same salt value as the original
        /// hash.
        /// </summary>
        /// <param name="plainText">
        /// Plain text to be verified against the specified hash. The function
        /// does not check whether this parameter is null.
        /// </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="hashValue">
        /// Base64-encoded hash value produced by ComputeHash function. This value
        /// includes the original salt appended to it.
        /// </param>
        /// <returns>
        /// If computed hash mathes the specified hash the function the return
        /// value is true; otherwise, the function returns false.
        /// </returns>
        public static bool VerifyHash(string   plainText,
                                      string   hashAlgorithm,
                                      string   hashValue)
        {
            // Convert base64-encoded hash value into a byte array.
            byte[] hashWithSaltBytes = Convert.FromBase64String(hashValue);
            
            // We must know size of hash (without salt).
            int hashSizeInBits, hashSizeInBytes;
            
            // Make sure that hashing algorithm name is specified.
            if (hashAlgorithm == null)
                hashAlgorithm = "";
            
            // Size of hash is based on the specified algorithm.
            switch (hashAlgorithm.ToUpper())
            {
                case "SHA1":
                    hashSizeInBits = 160;
                    break;
    
                case "SHA256":
                    hashSizeInBits = 256;
                    break;
    
                case "SHA384":
                    hashSizeInBits = 384;
                    break;
    
                case "SHA512":
                    hashSizeInBits = 512;
                    break;
    
                default: // Must be MD5
                    hashSizeInBits = 128;
                    break;
            }
    
            // Convert size of hash from bits to bytes.
            hashSizeInBytes = hashSizeInBits / 8;
    
            // Make sure that the specified hash value is long enough.
            if (hashWithSaltBytes.Length < hashSizeInBytes)
                return false;
    
            // Allocate array to hold original salt bytes retrieved from hash.
            byte[] saltBytes = new byte[hashWithSaltBytes.Length - 
                                        hashSizeInBytes];
    
            // Copy salt from the end of the hash to the new array.
            for (int i=0; i < saltBytes.Length; i++)
                saltBytes[i] = hashWithSaltBytes[hashSizeInBytes + i];
    
            // Compute a new hash string.
            string expectedHashString = 
                        ComputeHash(plainText, hashAlgorithm, saltBytes);
    
            // If the computed hash matches the specified hash,
            // the plain text value must be correct.
            return (hashValue == expectedHashString);
        }
    }
    
    /// <summary>
    /// Illustrates the use of the SimpleHash class.
    /// </summary>
    public class SimpleHashTest
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            string password      = "myP@5sw0rd";  // original password
            string wrongPassword = "password";    // wrong password
     
            string passwordHashMD5 = 
                   SimpleHash.ComputeHash(password, "MD5", null);
            string passwordHashSha1 = 
                   SimpleHash.ComputeHash(password, "SHA1", null);
            string passwordHashSha256 = 
                   SimpleHash.ComputeHash(password, "SHA256", null);
            string passwordHashSha384 = 
                   SimpleHash.ComputeHash(password, "SHA384", null);
            string passwordHashSha512 = 
                   SimpleHash.ComputeHash(password, "SHA512", null);
    
            Console.WriteLine("COMPUTING HASH VALUES\r\n");
            Console.WriteLine("MD5   : {0}", passwordHashMD5);
            Console.WriteLine("SHA1  : {0}", passwordHashSha1);
            Console.WriteLine("SHA256: {0}", passwordHashSha256);
            Console.WriteLine("SHA384: {0}", passwordHashSha384);
            Console.WriteLine("SHA512: {0}", passwordHashSha512);
            Console.WriteLine("");
    
            Console.WriteLine("COMPARING PASSWORD HASHES\r\n");
            Console.WriteLine("MD5    (good): {0}",
                                SimpleHash.VerifyHash(
                                password, "MD5", 
                                passwordHashMD5).ToString());
            Console.WriteLine("MD5    (bad) : {0}",
                                SimpleHash.VerifyHash(
                                wrongPassword, "MD5", 
                                passwordHashMD5).ToString());
            Console.WriteLine("SHA1   (good): {0}",
                                SimpleHash.VerifyHash(
                                password, "SHA1", 
                                passwordHashSha1).ToString());
            Console.WriteLine("SHA1   (bad) : {0}",
                                SimpleHash.VerifyHash(
                                wrongPassword, "SHA1", 
                                passwordHashSha1).ToString());
            Console.WriteLine("SHA256 (good): {0}",
                                SimpleHash.VerifyHash(
                                password, "SHA256", 
                                passwordHashSha256).ToString());
            Console.WriteLine("SHA256 (bad) : {0}",
                                SimpleHash.VerifyHash(
                                wrongPassword, "SHA256", 
                                passwordHashSha256).ToString());
            Console.WriteLine("SHA384 (good): {0}",
                                SimpleHash.VerifyHash(
                                password, "SHA384", 
                                passwordHashSha384).ToString());
            Console.WriteLine("SHA384 (bad) : {0}", 
                                SimpleHash.VerifyHash(
                                wrongPassword, "SHA384", 
                                passwordHashSha384).ToString());
            Console.WriteLine("SHA512 (good): {0}",
                                SimpleHash.VerifyHash(
                                password, "SHA512", 
                                passwordHashSha512).ToString());
            Console.WriteLine("SHA512 (bad) : {0}",
                                SimpleHash.VerifyHash(
                                wrongPassword, "SHA512", 
                                passwordHashSha512).ToString());
        }
    }
    //
    // END OF FILE
    ///////////////////////////////////////////////////////////////////////////////

    http://www.obviex.com/samples/hash.aspx
  • 相关阅读:
    https 证书
    js 压缩
    身份证认证
    在 Visual Studio 2015 中关闭系统级的 Runtime Exceptions
    在 Visual Studio 2015 中关闭 Browser Link
    List<T>.ForEach()的使用
    使用Microsoft.Practices.EnterpriseLibrary.Validation.dll验证类成员
    jQuery.filter()的强大功能
    jQuery Checkbox Selected
    Get SQL String From Query Object In Entity Framework
  • 原文地址:https://www.cnblogs.com/Kazaf/p/2306354.html
Copyright © 2011-2022 走看看