Hash i hasła soli w C#

Właśnie przeglądałem jeden z artykułów Davidhaydena o Hashowaniu haseł użytkowników .

Naprawdę nie mogę zrozumieć, co on próbuje osiągnąć.

Oto jego kod:

private static string CreateSalt(int size)
{
    //Generate a cryptographic random number.
    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    byte[] buff = new byte[size];
    rng.GetBytes(buff);

    // Return a Base64 string representation of the random number.
    return Convert.ToBase64String(buff);
}

private static string CreatePasswordHash(string pwd, string salt)
{
    string saltAndPwd = String.Concat(pwd, salt);
    string hashedPwd =
        FormsAuthentication.HashPasswordForStoringInConfigFile(
        saltAndPwd, "sha1");
    return hashedPwd;
}

Czy jest jakaś inna metoda C# do hashowania haseł i dodawania do nich soli?

Author: DuckMaestro, 2010-01-26

14 answers

W rzeczywistości jest to trochę dziwne, z konwersjami ciągów-które dostawca członkostwa robi, aby umieścić je w plikach konfiguracyjnych. Hasze i sole są binarnymi blobami, nie musisz ich przekonwertować na ciągi, chyba że chcesz umieścić je w plikach tekstowych.

In my book, Beginning ASP.NET bezpieczeństwo , (oh wreszcie, pretekst do pimp The book) robię następujące

static byte[] GenerateSaltedHash(byte[] plainText, byte[] salt)
{
  HashAlgorithm algorithm = new SHA256Managed();

  byte[] plainTextWithSaltBytes = 
    new byte[plainText.Length + salt.Length];

  for (int i = 0; i < plainText.Length; i++)
  {
    plainTextWithSaltBytes[i] = plainText[i];
  }
  for (int i = 0; i < salt.Length; i++)
  {
    plainTextWithSaltBytes[plainText.Length + i] = salt[i];
  }

  return algorithm.ComputeHash(plainTextWithSaltBytes);            
}
Generacja soli jest przykładem w pytaniu. Możesz przekonwertować tekst na tablice bajtowe za pomocą Encoding.UTF8.GetBytes(string). Jeśli musisz przekonwertować hash na jego reprezentację łańcuchową, możesz użyć Convert.ToBase64String i Convert.FromBase64String, Aby przekonwertować go z powrotem.

Należy zauważyć, że nie można użyć operatora równości na tablicach bajtów, sprawdza on referencje i dlatego należy po prostu zapętlić obie tablice sprawdzając każdy bajt w ten sposób

public static bool CompareByteArrays(byte[] array1, byte[] array2)
{
  if (array1.Length != array2.Length)
  {
    return false;
  }

  for (int i = 0; i < array1.Length; i++)
  {
    if (array1[i] != array2[i])
    {
      return false;
    }
  }

  return true;
}

Zawsze używaj Nowej Soli na hasło. Sole nie muszą być utrzymywane w tajemnicy i mogą być przechowywane obok samego haszu.

 251
Author: blowdart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-14 10:29:19

Co powiedział blowdart, ale z nieco mniejszym kodem. Użyj Linq lub CopyTo do łączenia tablic.

public static byte[] Hash(string value, byte[] salt)
{
    return Hash(Encoding.UTF8.GetBytes(value), salt);
}

public static byte[] Hash(byte[] value, byte[] salt)
{
    byte[] saltedValue = value.Concat(salt).ToArray();
    // Alternatively use CopyTo.
    //var saltedValue = new byte[value.Length + salt.Length];
    //value.CopyTo(saltedValue, 0);
    //salt.CopyTo(saltedValue, value.Length);

    return new SHA256Managed().ComputeHash(saltedValue);
}

Linq ma również łatwy sposób na porównanie tablic bajtowych.

public bool ConfirmPassword(string password)
{
    byte[] passwordHash = Hash(password, _passwordSalt);

    return _passwordHash.SequenceEqual(passwordHash);
}

Zanim jednak wdrożysz cokolwiek z tego, Sprawdź Ten post. Do hashowania haseł możesz potrzebować powolnego algorytmu hashowania, a nie szybkiego.

W tym celu istnieje Rfc2898DeriveBytes klasy, która jest wolna (i może być wolniejsza) i może odpowiedzieć na drugą część pierwotnego pytania w tym, że może wziąć hasło i sól i zwrócić hash. Zobacz to pytanie aby uzyskać więcej informacji. Uwaga, Wymiana stosu używa Rfc2898DeriveBytes do hashowania haseł (kod źródłowy tutaj ).

 48
Author: Adam Boddington,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-18 12:38:11

Czytałem, że funkcje haszujące, takie jak SHA256, nie były przeznaczone do przechowywania haseł: https://patrickmn.com/security/storing-passwords-securely/#notpasswordhashes

Zamiast adaptacyjnych funkcji wyprowadzania kluczy, takich jak PBKDF2, bcrypt lub scrypt były. Oto oparty na PBKDF2, który Microsoft napisał dla PasswordHasher w swoim Microsoft.AspNet.Biblioteka tożsamości:

/* =======================
 * HASHED PASSWORD FORMATS
 * =======================
 * 
 * Version 3:
 * PBKDF2 with HMAC-SHA256, 128-bit salt, 256-bit subkey, 10000 iterations.
 * Format: { 0x01, prf (UInt32), iter count (UInt32), salt length (UInt32), salt, subkey }
 * (All UInt32s are stored big-endian.)
 */

public string HashPassword(string password)
{
    var prf = KeyDerivationPrf.HMACSHA256;
    var rng = RandomNumberGenerator.Create();
    const int iterCount = 10000;
    const int saltSize = 128 / 8;
    const int numBytesRequested = 256 / 8;

    // Produce a version 3 (see comment above) text hash.
    var salt = new byte[saltSize];
    rng.GetBytes(salt);
    var subkey = KeyDerivation.Pbkdf2(password, salt, prf, iterCount, numBytesRequested);

    var outputBytes = new byte[13 + salt.Length + subkey.Length];
    outputBytes[0] = 0x01; // format marker
    WriteNetworkByteOrder(outputBytes, 1, (uint)prf);
    WriteNetworkByteOrder(outputBytes, 5, iterCount);
    WriteNetworkByteOrder(outputBytes, 9, saltSize);
    Buffer.BlockCopy(salt, 0, outputBytes, 13, salt.Length);
    Buffer.BlockCopy(subkey, 0, outputBytes, 13 + saltSize, subkey.Length);
    return Convert.ToBase64String(outputBytes);
}

public bool VerifyHashedPassword(string hashedPassword, string providedPassword)
{
    var decodedHashedPassword = Convert.FromBase64String(hashedPassword);

    // Wrong version
    if (decodedHashedPassword[0] != 0x01)
        return false;

    // Read header information
    var prf = (KeyDerivationPrf)ReadNetworkByteOrder(decodedHashedPassword, 1);
    var iterCount = (int)ReadNetworkByteOrder(decodedHashedPassword, 5);
    var saltLength = (int)ReadNetworkByteOrder(decodedHashedPassword, 9);

    // Read the salt: must be >= 128 bits
    if (saltLength < 128 / 8)
    {
        return false;
    }
    var salt = new byte[saltLength];
    Buffer.BlockCopy(decodedHashedPassword, 13, salt, 0, salt.Length);

    // Read the subkey (the rest of the payload): must be >= 128 bits
    var subkeyLength = decodedHashedPassword.Length - 13 - salt.Length;
    if (subkeyLength < 128 / 8)
    {
        return false;
    }
    var expectedSubkey = new byte[subkeyLength];
    Buffer.BlockCopy(decodedHashedPassword, 13 + salt.Length, expectedSubkey, 0, expectedSubkey.Length);

    // Hash the incoming password and verify it
    var actualSubkey = KeyDerivation.Pbkdf2(providedPassword, salt, prf, iterCount, subkeyLength);
    return actualSubkey.SequenceEqual(expectedSubkey);
}

private static void WriteNetworkByteOrder(byte[] buffer, int offset, uint value)
{
    buffer[offset + 0] = (byte)(value >> 24);
    buffer[offset + 1] = (byte)(value >> 16);
    buffer[offset + 2] = (byte)(value >> 8);
    buffer[offset + 3] = (byte)(value >> 0);
}

private static uint ReadNetworkByteOrder(byte[] buffer, int offset)
{
    return ((uint)(buffer[offset + 0]) << 24)
        | ((uint)(buffer[offset + 1]) << 16)
        | ((uint)(buffer[offset + 2]) << 8)
        | ((uint)(buffer[offset + 3]));
}

Uwaga Wymaga Microsoft.AspNetCore.Kryptografia.KeyDerivation zainstalowany pakiet nuget, który wymaga. Net Standard 2.0 (. NET 4.6.1 lub nowszy). Dla wcześniejszych wersji. NET zobacz klasę Crypto z systemu Microsoftu.Www.Biblioteka pomocników.

Aktualizacja Listopad 2015
Zaktualizowana odpowiedź na użycie implementacji z innej biblioteki Microsoft, która używa hashowania PBKDF2-HMAC-SHA256 zamiast PBKDF2-HMAC-SHA1 (Uwaga PBKDF2-HMAC-SHA1 jest nadal bezpieczne Jeśli iterCount jest wystarczająco wysoko). Możesz sprawdzić źródło uproszczony kod został skopiowany, ponieważ faktycznie obsługuje walidację i aktualizowanie hashów zaimplementowanych z poprzedniej odpowiedzi, przydatne, jeśli chcesz zwiększyć liczbę iterCount w przyszłości.

 33
Author: Michael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-11-15 01:25:46

Sól jest używana, aby dodać dodatkowy poziom złożoności do haszu, aby utrudnić łamanie siłowe.

From an article on Sitepoint :

Haker może jeszcze wykonać to się nazywa atak słownikowy. Złośliwe strony mogą dokonać atak słownikowy poprzez branie, za przykład, 100 000 haseł, które wiedzieć, że ludzie często używają (np. miasto nazwy, drużyny sportowe itp.), hash them, a następnie porównać każdy wpis w słownik dla każdego wiersza w tabela bazy danych. Jeśli hakerzy znajdą mecz, bingo! Mają Twoje hasło. Aby rozwiązać ten problem, jednak my trzeba tylko sól hash.

Aby posolić hash, po prostu wymyślamy losowy ciąg tekstu, połącz go z hasłem dostarczone przez użytkownika, a następnie hashować zarówno losowo generowany ciąg znaków i hasło razem jako jedna wartość. My następnie oszczędzaj zarówno hash, jak i sól jako oddzielne pola w obrębie użytkowników stolik.

W tym scenariusz, nie tylko haker musi odgadnąć hasło, muszą odgadnąć sól. Dodanie soli do czystego tekstu poprawia bezpieczeństwo: teraz, jeśli haker spróbuje atak słownikowy, musi hashować jego 100 000 wpisów z solą każdego wiersz użytkownika. Chociaż wciąż jest możliwe, szanse na włamanie sukces zmniejsza się radykalnie.

Nie ma metody, która automatycznie robi to w. NET, więc musisz przejść z rozwiązaniem powyżej.

 25
Author: Seb Nilsson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-26 09:30:21

Stworzyłem klasę, która ma następującą metodę:

  1. Utwórz Sól

  2. Hash Input

  3. Zweryfikuj dane wejściowe

    public class CryptographyProcessor
    {
        public string CreateSalt(int size)
        {
            //Generate a cryptographic random number.
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            byte[] buff = new byte[size];
            rng.GetBytes(buff);
            return Convert.ToBase64String(buff);
        }
    
        public string GenerateHash(string input, string salt)
        { 
            byte[] bytes = Encoding.UTF8.GetBytes(input + salt);
            SHA256Managed sHA256ManagedString = new SHA256Managed();
            byte[] hash = sHA256ManagedString.ComputeHash(bytes);
            return Convert.ToBase64String(hash);
        }
    
        public bool AreEqual(string plainTextInput, string hashedInput, string salt)
        {
            string newHashedPin = GenerateHash(plainTextInput, salt);
            return newHashedPin.Equals(hashedInput); 
        }
    }
    
 16
Author: Bamidele Alegbe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-05 15:37:32

Bah, tak jest lepiej! http://sourceforge.net/projects/pwdtknet / i jest lepiej, ponieważ ..... wykonuje Rozciąganie klucza i używa HMACSHA512 :)

 5
Author: thashiznets,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-23 10:02:36

Stworzyłem bibliotekę SimpleHashing.Net aby ułatwić proces haszowania za pomocą podstawowych klas dostarczanych przez Microsoft. Zwykłe SHA nie wystarcza już do bezpiecznego przechowywania haseł.

Biblioteka wykorzystuje ideę formatu hash z Bcrypt, ale ponieważ nie ma oficjalnej implementacji MS, wolę używać tego, co jest dostępne w frameworku (tj. PBKDF2), ale jest to trochę zbyt trudne.

Jest to szybki przykład, jak korzystać z biblioteka:

ISimpleHash simpleHash = new SimpleHash();

// Creating a user hash, hashedPassword can be stored in a database
// hashedPassword contains the number of iterations and salt inside it similar to bcrypt format
string hashedPassword = simpleHash.Compute("Password123");

// Validating user's password by first loading it from database by username
string storedHash = _repository.GetUserPasswordHash(username);
isPasswordValid = simpleHash.Verify("Password123", storedHash);
 4
Author: Ilya Chernomordik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-18 19:41:02

Użyj System.Web.Helpers.Crypto pakietu NuGet od Microsoftu. Automatycznie dodaje sól do hash.

Hasasz hasło tak: var hash = Crypto.HashPassword("foo");

Weryfikujesz hasło takie jak: var verified = Crypto.VerifyHashedPassword(hash, "foo");

 4
Author: Kai Hartmann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-23 09:22:44

Tak to robię.. Tworzę hash i przechowuję go za pomocą ProtectedData api:

    public static string GenerateKeyHash(string Password)
    {
        if (string.IsNullOrEmpty(Password)) return null;
        if (Password.Length < 1) return null;

        byte[] salt = new byte[20];
        byte[] key = new byte[20];
        byte[] ret = new byte[40];

        try
        {
            using (RNGCryptoServiceProvider randomBytes = new RNGCryptoServiceProvider())
            {
                randomBytes.GetBytes(salt);

                using (var hashBytes = new Rfc2898DeriveBytes(Password, salt, 10000))
                {
                    key = hashBytes.GetBytes(20);
                    Buffer.BlockCopy(salt, 0, ret, 0, 20);
                    Buffer.BlockCopy(key, 0, ret, 20, 20);
                }
            }
            // returns salt/key pair
            return Convert.ToBase64String(ret);
        }
        finally
        {
            if (salt != null)
                Array.Clear(salt, 0, salt.Length);
            if (key != null)
                Array.Clear(key, 0, key.Length);
            if (ret != null)
                Array.Clear(ret, 0, ret.Length);
        } 
    }

    public static bool ComparePasswords(string PasswordHash, string Password)
    {
        if (string.IsNullOrEmpty(PasswordHash) || string.IsNullOrEmpty(Password)) return false;
        if (PasswordHash.Length < 40 || Password.Length < 1) return false;

        byte[] salt = new byte[20];
        byte[] key = new byte[20];
        byte[] hash = Convert.FromBase64String(PasswordHash);

        try
        {
            Buffer.BlockCopy(hash, 0, salt, 0, 20);
            Buffer.BlockCopy(hash, 20, key, 0, 20);

            using (var hashBytes = new Rfc2898DeriveBytes(Password, salt, 10000))
            {
                byte[] newKey = hashBytes.GetBytes(20);

                if (newKey != null)
                    if (newKey.SequenceEqual(key))
                        return true;
            }
            return false;
        }
        finally
        {
            if (salt != null)
                Array.Clear(salt, 0, salt.Length);
            if (key != null)
                Array.Clear(key, 0, key.Length);
            if (hash != null)
                Array.Clear(hash, 0, hash.Length);
        }
    }

    public static byte[] DecryptData(string Data, byte[] Salt)
    {
        if (string.IsNullOrEmpty(Data)) return null;

        byte[] btData = Convert.FromBase64String(Data);

        try
        {
            return ProtectedData.Unprotect(btData, Salt, DataProtectionScope.CurrentUser);
        }
        finally
        {
            if (btData != null)
                Array.Clear(btData, 0, btData.Length);
        }
    }

    public static string EncryptData(byte[] Data, byte[] Salt)
    {
        if (Data == null) return null;
        if (Data.Length < 1) return null;

        byte[] buffer = new byte[Data.Length];

        try
        {
            Buffer.BlockCopy(Data, 0, buffer, 0, Data.Length);
            return System.Convert.ToBase64String(ProtectedData.Protect(buffer, Salt, DataProtectionScope.CurrentUser));
        }
        finally
        {
            if (buffer != null)
                Array.Clear(buffer, 0, buffer.Length);
        }
    }
 2
Author: JGU,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-11 15:02:03

Czytam wszystkie odpowiedzi i myślę, że wystarczy, szczególnie @Michael artykuły z powolnym hashowaniem i @CodesInChaos dobre komentarze, ale postanowiłem udostępnić mój fragment kodu do hashowania/walidacji, który może być przydatny i nie wymaga [Microsoft.AspNet.Kryptografia.KeyDerivation ].

    private static bool SlowEquals(byte[] a, byte[] b)
            {
                uint diff = (uint)a.Length ^ (uint)b.Length;
                for (int i = 0; i < a.Length && i < b.Length; i++)
                    diff |= (uint)(a[i] ^ b[i]);
                return diff == 0;
            }

    private static byte[] PBKDF2(string password, byte[] salt, int iterations, int outputBytes)
            {
                Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(password, salt);
                pbkdf2.IterationCount = iterations;
                return pbkdf2.GetBytes(outputBytes);
            }

    private static string CreateHash(string value, int salt_bytes, int hash_bytes, int pbkdf2_iterations)
            {
                // Generate a random salt
                RNGCryptoServiceProvider csprng = new RNGCryptoServiceProvider();
                byte[] salt = new byte[salt_bytes];
                csprng.GetBytes(salt);

                // Hash the value and encode the parameters
                byte[] hash = PBKDF2(value, salt, pbkdf2_iterations, hash_bytes);

                //You need to return the salt value too for the validation process
                return Convert.ToBase64String(hash) + ":" + 
                       Convert.ToBase64String(hash);
            }

    private static bool ValidateHash(string pureVal, string saltVal, string hashVal, int pbkdf2_iterations)
            {
                try
                {
                    byte[] salt = Convert.FromBase64String(saltVal);
                    byte[] hash = Convert.FromBase64String(hashVal);

                    byte[] testHash = PBKDF2(pureVal, salt, pbkdf2_iterations, hash.Length);
                    return SlowEquals(hash, testHash);
                }
                catch (Exception ex)
                {
                    return false;
                }
            }

Proszę zwrócić uwagę na funkcję SlowEquals, która jest tak ważna, w końcu mam nadzieję, że to pomoże i proszę nie wahaj się doradzić mi o lepszych podejściach.

 2
Author: QMaster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-16 11:19:03

Jeśli nie używasz asp.net lub. NET core istnieje również łatwy sposób w projektach>=. Net Standard 2.0.

Najpierw można ustawić żądany rozmiar hash, salt i numer iteracji, który jest związany z czasem generowania hash:

private const int SaltSize = 32;
private const int HashSize = 32;
private const int IterationCount = 10000;

Aby wygenerować hasło hash i salt możesz użyć czegoś takiego:

public static string GeneratePasswordHash(string password, out string salt)
{
    using (Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, SaltSize))
    {
        rfc2898DeriveBytes.IterationCount = IterationCount;
        byte[] hashData = rfc2898DeriveBytes.GetBytes(HashSize);
        byte[] saltData = rfc2898DeriveBytes.Salt;
        salt = Convert.ToBase64String(saltData);
        return Convert.ToBase64String(hashData);
    }
}

Aby sprawdzić, czy hasło wprowadzone przez użytkownika jest poprawne, możesz sprawdzić wartości w swojej bazie danych:

public static bool VerifyPassword(string password, string passwordHash, string salt)
{
    using (Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, SaltSize))
    {
        rfc2898DeriveBytes.IterationCount = IterationCount;
        rfc2898DeriveBytes.Salt = Convert.FromBase64String(salt);
        byte[] hashData = rfc2898DeriveBytes.GetBytes(HashSize);
        return Convert.ToBase64String(hashData) == passwordHash;
    }
}

Następująca Jednostka test pokazuje użycie:

string password = "MySecret";

string passwordHash = PasswordHasher.GeneratePasswordHash(password, out string salt);

Assert.True(PasswordHasher.VerifyPassword(password, passwordHash, salt));
Assert.False(PasswordHasher.VerifyPassword(password.ToUpper(), passwordHash, salt));

Microsoft Rfc2898DeriveBytes Source

 1
Author: eugstman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-14 19:39:00

W odpowiedzi na tę część oryginalnego pytania "czy jest jakaś inna metoda hashowania haseł w C#" można to osiągnąć za pomocą ASP.NET tożsamość v3.0 https://www.nuget.org/packages/Microsoft.AspNet.Identity.EntityFramework/3.0.0-rc1-final

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using System.Security.Principal;

namespace HashTest{


    class Program
    {
        static void Main(string[] args)
        {

            WindowsIdentity wi = WindowsIdentity.GetCurrent();

            var ph = new PasswordHasher<WindowsIdentity>();

            Console.WriteLine(ph.HashPassword(wi,"test"));

            Console.WriteLine(ph.VerifyHashedPassword(wi,"AQAAAAEAACcQAAAAEA5S5X7dmbx/NzTk6ixCX+bi8zbKqBUjBhID3Dg1teh+TRZMkAy3CZC5yIfbLqwk2A==","test"));

        }
    }


}
 -1
Author: Dave Cornall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-30 12:12:33
 protected void m_GenerateSHA256_Button1_Click(objectSender, EventArgs e)
{
string salt =createSalt(10);
string hashedPassword=GenerateSHA256Hash(m_UserInput_TextBox.Text,Salt);
m_SaltHash_TextBox.Text=Salt;
 m_SaltSHA256Hash_TextBox.Text=hashedPassword;

}
 public string createSalt(int size)
{
 var rng= new System.Security.Cyptography.RNGCyptoServiceProvider();
 var buff= new byte[size];
rng.GetBytes(buff);
 return Convert.ToBase64String(buff);
}


 public string GenerateSHA256Hash(string input,string salt)
{
 byte[]bytes=System.Text.Encoding.UTF8.GetBytes(input+salt);
 new System.Security.Cyptography.SHA256Managed();
 byte[]hash=sha256hashString.ComputedHash(bytes);
 return bytesArrayToHexString(hash);
  }
 -1
Author: ankush shukla,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-24 18:05:21
create proc [dbo].[hash_pass] @family nvarchar(50), @username nvarchar(50), @pass nvarchar(Max),``` @semat nvarchar(50), @tell nvarchar(50)

as insert into tbl_karbar values (@family,@username,(select HASHBYTES('SHA1' ,@pass)),@semat,@tell)
 -7
Author: ehsan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-16 12:08:04