Example #1
0
        /// <summary>
        /// This method will compute a hash of a password and salt combination.  As a result it does need to take the secure string and read
        /// through its contents to compute the hash, this is probably the only time the secure string is not secure, other than when its
        /// created in the first place.
        /// </summary>
        /// <param name="password">The password that is to be hashed.</param>
        /// <param name="salt">The salt to hash with the password so that the password hash is more secure</param>
        /// <exception cref="ArgumentException">Thrown if the password is empty or null or if the salt is not initialised</exception>
        /// <returns>A string representing that password and salt, this string can be passed around and persisted wtihout fear of revealing the password</returns>
        public static string ComputeSaltedHash(SecureString password, PasswordSalt salt)
        {
            #region entry checking

            // TODO b.Assert(password != null, "The password SecureString can not be null when given to SaltyPassword::ComputeSaltedHash");
            // TODO Bilge.Assert((salt.IntegerSalt != 0), "When calling SaltyPassword::ComputeSaltedHash All of the salt bytes are zero.", "This is not valid salt, call SaltyPassword.Salt.FillWithSalt()");

            if ((password == null) || (password.Length == 0))
            {
                throw new ArgumentException("The password supplied was not valid.");
            }
            if (salt.IntegerSalt == 0)
            {
                throw new ArgumentException("The salt supplied is not valid.");
            }

            #endregion

            // Create Byte array of password string
            ASCIIEncoding encoder = new ASCIIEncoding();
            Byte[]        passwordAndSaltCombo = new byte[password.Length + 4];

            passwordAndSaltCombo[0] = salt.Byte1;
            passwordAndSaltCombo[1] = salt.Byte2;
            passwordAndSaltCombo[2] = salt.Byte3;
            passwordAndSaltCombo[3] = salt.Byte4;

            // Now we take the bytes from the secure string and place them into a byte array so that we can
            // perform the hash on them.  This probably moves them out of secure encrypted memory negating the
            // whole secure string thing.
            IntPtr ptr = Marshal.SecureStringToBSTR(password);
            try {
                for (int i = 0; i < password.Length; i++)
                {
                    // this so must break unicode.
                    passwordAndSaltCombo[i + 4] = Marshal.ReadByte(ptr, i * sizeof(char));
                }
            } finally {
                // Free and Zero the temp we have been using.
                Marshal.ZeroFreeBSTR(ptr);
            }

            //return the calculated hash.
            string resultingHash;
            if (HashesAreB64Encoded)
            {
                resultingHash = Convert.ToBase64String(SHA1.Create().ComputeHash(passwordAndSaltCombo));
            }
            else
            {
                resultingHash = encoder.GetString(SHA1.Create().ComputeHash(passwordAndSaltCombo));
            }
            return(resultingHash);
        }
Example #2
0
 private SaltyPassword()
 {
     this.Password = new SecureString();
     this.Salt     = new PasswordSalt();
 }
Example #3
0
 public SaltyPassword(SecureString password, PasswordSalt pws)
 {
     this.Password         = password;
     this.Salt.IntegerSalt = pws.IntegerSalt;
 }