C # karma ve tuz şifreleri


178

DavidHayden'in Hashing Kullanıcı Parolaları ile ilgili makalelerinden birini inceliyordum .

Gerçekten elde etmeye çalıştığı şeyi elde edemiyorum.

İşte onun kodu:

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;
}

Parolaları karma yapmak ve ona tuz eklemek için başka bir C # yöntemi var mı?


Burada tuz ile karma yapan bir kütüphane encrypto.codeplex.com
Omu

6
Tuz üretmek için ilk yöntemdeki boyut için neyi geçmelisiniz?
Shane LeBlanc

6
Bağlantı koptu.
osmanraifgunes

@ShaneLeBlanc En az fonksiyon çıkışı olan bit kadar olmalıdır. SHA1kripto sınıfı değildir, bu nedenle en azından SHA256256 bit veya 32 bayt çıktı veren kullanmalısınız . ANCAK, 256 bit 64 tabanına kolayca dönüştürülemez, çünkü her base64 karakter 6 bit kodlar ve 256 tamamen 6 ile bölünemez. Bu nedenle 6 (base64 için) ve 8 (bayttaki bitler için) ortak paydaya ihtiyacınız vardır. 264 bit veya 33 bayt olan 256 bitten fazla. TLDR: 33.
VSO

Yanıtlar:


248

Aslında bu, üyelik sağlayıcının yapılandırma dosyalarına koymak için yaptığı dize dönüşümleriyle biraz garip. Karmalar ve tuzlar ikili lekelerdir, metin dosyalarına koymak istemiyorsanız bunları dizelere dönüştürmeniz gerekmez.

Kitabımda, ASP.NET Güvenliği Başlıyor , (oh nihayet, kitabı pezevenk etmek için bir bahane) Aşağıdakileri yaparım

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);            
}

Tuz üretimi söz konusu örnektir. Kullanarak metni bayt dizilerine dönüştürebilirsiniz Encoding.UTF8.GetBytes(string). Onun dize gösterimine bir karma dönüştürmek gerekiyorsa kullanabileceğiniz Convert.ToBase64Stringve Convert.FromBase64Stringgeri dönüştürmek için.

Eşitlik operatörünü bayt dizilerinde kullanamayacağınızı, referansları kontrol ettiğinizi ve böylece her bir baytı kontrol ederek her iki diziyi de döngüye sokmanız gerektiğini unutmayın.

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;
}

Parola başına daima yeni bir tuz kullanın. Tuzlar gizli tutulmak zorunda değildir ve karmanın yanında saklanabilir.


3
Bu tavsiye için teşekkürler - gerçekten başlamama yardımcı oldu. Ayrıca, bu uygulamada söylenenlerin çoğunun iyi bir pratik tavsiye olduğunu ve bu yazıda söylenenlerin çoğunu yansıttığını bulduğum < dijksterhuis.org/creating-salted-hash-values-in-c > bağlantısına rastladım
Alex P

18
CompareByteArrays için nifty LINQ bildirimi refactor return array1.Length == array2.Length && !array1.Where((t, i) => t != array2[i]).Any();
avcı

6
@Brettski Teknik olarak, evet, ancak her kullanıcı için benzersiz bir tuza sahip olmak Rainbow Tables'ı (genellikle karma şifreleri kırmanın en etkili yolu olarak kabul edilir) pratik olarak işe yaramaz hale getirir. Bu hızlı bir görünüm , şifrelerin nasıl güvenli bir şekilde saklanacağına ve neden / nasıl çalıştığına dair derinlemesine ancak ezici bir genel bakış sağlar.
Ranger

3
@hunter: sabit zaman yapmak için bir .ToList () eklemelisiniz. örneğin: return array1.Length == dizi2.Length &&! dizi1.Where ((t, i) => t! = dizi2 [i]). ToList (). Herhangi biri (); Aksi takdirde, LINQ eşit olmayan bir bayt bulur bulmaz geri döner.
Alex Rouillard

17
Hızlı karma işlevini kullanmak için -1. PBKDF2, bcrypt veya scrypt gibi yavaş bir yapı kullanın.
CodesInChaos

48

Blowdart ne dedi, ama biraz daha az kodla. CopyToDizileri birleştirmek için Linq veya kullanın .

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, bayt dizilerinizi de karşılaştırmanın kolay bir yoluna sahiptir.

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

    return _passwordHash.SequenceEqual(passwordHash);
}

Ancak bunlardan herhangi birini uygulamadan önce bu gönderiye göz atın . Parola karması için hızlı bir algoritma değil, yavaş bir karma algoritması isteyebilirsiniz.

Bu amaçla Rfc2898DeriveBytes, yavaş olan (ve daha yavaş yapılabilen) sınıf vardır ve orijinal sorunun ikinci kısmını bir şifre ve tuz alıp bir karma döndürebilmesi nedeniyle cevaplayabilir. Daha fazla bilgi için bu soruya bakın . Not, Stack ExchangeRfc2898DeriveBytes şifre karma (kaynak kodu burada ) için kullanıyor.


6
@MushinNoShin SHA256 hızlı bir karmadır. Parola karması, PBKDF2, bcrypt veya scrypt gibi yavaş bir karmaya ihtiyaç duyar. Bkz. Şifreleri güvenli bir şekilde sağlama? detaylar için.
CodesInChaos

32

SHA256 gibi karma işlevlerin şifreleri saklamak için gerçekten amaçlanmadığını okudum: https://patrickmn.com/security/storing-passwords-securely/#notpasswordhashes

Bunun yerine PBKDF2, bcrypt veya scrypt gibi uyarlanabilir anahtar türetme işlevleri vardı. İşte Microsoft'un Microsoft.AspNet.Identity kütüphanesinde PasswordHasher için yazdığı PBKDF2 tabanlı bir tane :

/* =======================
 * 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]));
}

Bunun için .NET Standard 2.0 (.NET 4.6.1 veya üstü) gerektiren Microsoft.AspNetCore.Cryptography.KeyDerivation nuget paketinin yüklü olması gerektiğini unutmayın . .NET'in önceki sürümleri için Microsoft'un System.Web.Helpers kitaplığındaki Crypto sınıfına bakın .

Güncelleme Kasım 2015
PBKDF2-HMAC-SHA1 yerine PBKDF2-HMAC-SHA256 karma kullanan farklı bir Microsoft kütüphanesinden bir uygulamanın kullanımı için cevap güncellendi ( iterCount yeterince yüksekse PBKDF2-HMAC- SHA1'in hala güvenli olduğunu unutmayın). Basitleştirilmiş kodun kopyalandığı kaynağı kontrol edebilir , çünkü önceki yanıttan uygulanan sağlama ve yükseltme karmaları işlenir, ileride iterCount'u artırmanız gerekiyorsa yararlıdır.


1
Daha yüksek bir sayıya PBKDF2IterCount artan belki değerinde, bkz Not security.stackexchange.com/q/3959 daha fazlası.
Michael

2
1) PBKDF2SubkeyLength20 bayta kadar azaltın . SHA1'in doğal boyutu budur ve bunun ötesine geçmek, saldırganı yavaşlatmadan savunucuyu yavaşlatır. 2) Yineleme sayısını artırmanızı öneririm. Performans bütçenize bağlı olarak 10k - 100k arasında öneriyorum. 3) Sabit bir zaman karşılaştırması da zarar vermez, ancak çok fazla pratik etkisi yoktur.
CodesInChaos

KeyDerivationPrf, KeyDerivation ve BlockCopy tanımsız, sınıfları nedir?
mrbengi

@mrbengi Belirtilen Microsoft.AspNet.Cryptography.KeyDerivation nuget paketini yüklediniz mi? Bu uygun değilse burada Nuget paketi gerektirmeyen bir sürümüdür. Buffer.BlockCopy Sistemin bir parçası olmalıdır.
Michael

1
Nuget paketi artık Microsoft.AspNetCore.Cryptography.KeyDerivation.
James Blake

25

Tuz, kaba kuvvet çatlağını zorlaştırmak için karmaya ekstra bir karmaşıklık seviyesi eklemek için kullanılır.

Sitepoint ile ilgili bir makaleden :

Bir bilgisayar korsanı hala sözlük saldırısı denen şeyi yapabilir. Kötü niyetli taraflar, örneğin insanların sık kullandıklarını bildikleri (örneğin şehir adları, spor takımları, vb.) 100.000 parola alarak, bunları karma hale getirip sözlükteki her girdiyi veritabanındaki her bir satırla karşılaştırarak sözlük saldırısı yapabilir. tablo. Bilgisayar korsanları bir eşleşme bulursa, tombala! Şifreniz var. Ancak bu sorunu çözmek için sadece hash tuzuna ihtiyacımız var.

Bir hash tuzlamak için, rastgele görünen bir metin dizesi buluruz, bunu kullanıcı tarafından sağlanan parolayla birleştiririz, sonra rastgele üretilen dize ve parolayı bir değer olarak bir araya getiririz. Ardından karma ve tuzu Kullanıcılar tablosunda ayrı alanlar olarak kaydederiz.

Bu senaryoda, bir bilgisayar korsanının sadece parolayı tahmin etmesi gerekmez, aynı zamanda tuzu da tahmin etmesi gerekir. Açık metne tuz eklemek güvenliği artırır: şimdi, bir bilgisayar korsanı sözlük saldırısına çalışırsa, 100.000 girişini her kullanıcı satırının tuzuyla karıştırmalıdır. Hala mümkün olmasına rağmen, hackleme şansı radikal bir şekilde azalıyor.

.NET'te bunu otomatik olarak yapan bir yöntem yoktur, bu nedenle yukarıdaki çözümle devam edeceksiniz.


Tuzlar, gökkuşağı masaları gibi şeylere karşı savunmak için kullanılır. Sözlük saldırılarına karşı savunmak için, iyi bir KDF gibi bir çalışma faktörü (anahtar germe olarak da bilinir) gereklidir: en.wikipedia.org/wiki/Key_stretching
Erwan Legrand

11

Aşağıdaki yöntemi olan bir sınıf oluşturdum:

  1. Tuz Yarat
  2. Karma Girişi
  3. Girişi doğrula

    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); 
          }
     }

    '



3

Microsoft tarafından sağlanan temel sınıflarla hash işlemini kolaylaştıracak bir kütüphane SimpleHashing.Net yaptım . Sıradan SHA, şifrelerin artık güvenli bir şekilde saklanması için yeterli değildir.

Kütüphane Bcrypt'ten karma biçimi fikrini kullanır, ancak resmi bir MS uygulaması olmadığından, çerçevede mevcut olanı (yani PBKDF2) kullanmayı tercih ederim, ancak kutudan biraz zor.

Bu, kitaplığın nasıl kullanılacağına dair hızlı bir örnektir:

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);

2

Ben bu şekilde .. Ben karma oluşturmak ve ProtectedDataapi kullanarak saklayın :

    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);
        }
    }

Kaydederken ve daha sonra karşılaştırırken nasıl arayabilirim?
SearchForKnowledge

2

Tüm cevapları okudum ve yavaşça hashing ve @CodesInChaos iyi yorumları olan özel olarak @Michael makalelerini düşünüyorum , ama yararlı olabilecek ve gerektirmeyen karma / doğrulama için kod snippet'i paylaşmaya karar verdim [ Microsoft.AspNet.Cryptography .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;
                }
            }

Lütfen çok önemli olan SlowEquals fonksiyonuna dikkat edin, Son olarak, bu yardım umuyoruz ve lütfen bana daha iyi yaklaşımlar hakkında tavsiyede bulunmaktan çekinmeyin.


Meşgul bir döngü oluşturmak yerine, neden meşgul olmayan bir gecikme yapmıyorsunuz? örneğin Task.Delay kullanarak. Bu bir kaba kuvvet girişimini geciktirir, ancak aktif ipliği engellemez.
gburton

@gburton Tavsiyeniz için teşekkürler. Kontrol edeceğim.
QMaster

CreateHash'te bir yazım hatası var: Tuz yerine Convert.ToBase64String'i (karma) kendiniz onaylıyorsunuz. Bunun dışında, bu, diğer yanıtlarla ilgili yorumlarda ortaya çıkan hemen hemen her sorunu çözen güzel bir cevaptır.
ZeRemz

2

System.Web.Helpers.CryptoMicrosoft'un NuGet paketini kullanın . Otomatik olarak karışıma tuz ekler.

Bunun gibi bir parola vardır: var hash = Crypto.HashPassword("foo");

Bunun gibi bir şifre doğrularsınız: var verified = Crypto.VerifyHashedPassword(hash, "foo");


1

Asp.net veya .net çekirdeğini kullanmazsanız, = = .Net Standard 2.0 projelerinde de kolay bir yol vardır.

İlk önce, karma üretiminin süresi ile ilişkili olan karma, tuz ve iterasyon numarasının istenen boyutunu ayarlayabilirsiniz:

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

Parola karması ve tuzunu oluşturmak için şöyle bir şey kullanabilirsiniz:

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);
    }
}

Kullanıcının girdiği parolanın geçerli olup olmadığını doğrulamak için veritabanınızdaki değerleri kontrol edebilirsiniz:

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;
    }
}

Aşağıdaki birim testi kullanımı gösterir:

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 Kaynağı


-1

Asıl sorunun "Parolaları karıştırmak için başka bir C # yöntemi var mı?" Sorusunun cevabını ASP.NET Identity v3.0 kullanarak yapabilirsiniz . 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
 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);
  }

diğer yöntem dize parola = HashPasswordForStoringInConfigFile (TextBox1.Text, SHA1)
ankush shukla

-6
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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.