c# - 如何在 UWP c# 中散列和/或加盐密码?

标签 c# hash uwp

<分区>

经过大量谷歌搜索后,我似乎真的无法找到如何在 c# UWP 中散列密码,我已经尝试过 Bcrypt,但它不适用于 RT。关于如何在 UWP 中散列密码的任何想法?这是我在 UWP 中的第一个应用程序,所以我认为一切都会像在 WPF 中一样工作,看来我错了。我已经尝试过 Nugetstore 的 BCRYPT,但在 UWP 上无法运行。

我只需要一种对字符串进行散列和/或加盐的简单方法,以及一种验证散列的简单方法。

最佳答案

这个方法怎么样(使用 System.Security.Cryptography):

  • To store user passwords in the database in a way that they cannot be extracted, the passwords need to be hashed using a one-way hashing algorithm such as SHA1

  • To do so, use the RNGCryptoServiceProvider to create a random salt, append the salt to the password, hash it using SHA1 CryptoServiceProvider class, and store the resulting string in the database along with the salt

  • The benefit provided by using a salted password is making a lookup table assisted dictionary attack against the stored values impractical, provided the salt is large enough

示例代码:

  // Create salted password to save in database.
  private byte [] CreateDbPassword(byte[] unsaltedPassword)
  {
     //Create a salt value.
     byte[] saltValue = new byte[saltLength];
     RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
     rng.GetBytes(saltValue);

     return CreateSaltedPassword(saltValue, unsaltedPassword);
  }

  // Create a salted password given the salt value.
  private byte[] CreateSaltedPassword(byte[] saltValue, byte[] unsaltedPassword)
  {
     // Add the salt to the hash.
     byte[] rawSalted  = new byte[unsaltedPassword.Length + saltValue.Length]; 
     unsaltedPassword.CopyTo(rawSalted,0);
     saltValue.CopyTo(rawSalted,unsaltedPassword.Length);

     //Create the salted hash.         
     SHA1 sha1 = SHA1.Create();
     byte[] saltedPassword = sha1.ComputeHash(rawSalted);

     // Add the salt value to the salted hash.
     byte[] dbPassword  = new byte[saltedPassword.Length + saltValue.Length];
     saltedPassword.CopyTo(dbPassword,0);
     saltValue.CopyTo(dbPassword,saltedPassword.Length);

     return dbPassword;
  }

     // Compare the hashed password against the stored password.
private bool ComparePasswords(byte[] storedPassword, byte[] hashedPassword)
{
   if (storedPassword == null || hashedPassword == null || hashedPassword.Length != storedPassword.Length - saltLength)
      return false;

   // Get the saved saltValue.
   byte[] saltValue = new byte[saltLength];
   int saltOffset = storedPassword.Length - saltLength;
   for (int i = 0; i < saltLength; i++)
      saltValue[i] = storedPassword[saltOffset + i];

   byte[] saltedPassword = CreateSaltedPassword(saltValue, hashedPassword);

   // Compare the values.
   return CompareByteArray(storedPassword, saltedPassword);
}

// Compare the contents of two byte arrays.
private bool CompareByteArray(byte[] array1, byte[] array2)
{
   if (array1.Length != array2.Length)
      return false;

   int mismatch = 0;
   for (int i = 0; i < array1.Length; i++)
   {
      mismatch |= array1[i] ^ array2[i];
   }
   return mismatch == 0;
}

MSDN:https://msdn.microsoft.com/en-us/library/aa288534(v=vs.71).aspx

更新 对于 UWP 应用,您需要使用命名空间 Windows.Security.Cryptography.Core:

public String SampleDeriveFromPbkdf(
    String strAlgName,
    UInt32 targetSize)
{
    // Open the specified algorithm.
    KeyDerivationAlgorithmProvider objKdfProv = KeyDerivationAlgorithmProvider.OpenAlgorithm(strAlgName);

    // Create a buffer that contains the secret used during derivation.
    String strSecret = "MyPassword";
    IBuffer buffSecret = CryptographicBuffer.ConvertStringToBinary(strSecret, BinaryStringEncoding.Utf8);

    // Create a random salt value.
    IBuffer buffSalt = CryptographicBuffer.GenerateRandom(32);

    // Specify the number of iterations to be used during derivation.
    UInt32 iterationCount = 10000;

    // Create the derivation parameters.
    KeyDerivationParameters pbkdf2Params = KeyDerivationParameters.BuildForPbkdf2(buffSalt, iterationCount);

    // Create a key from the secret value.
    CryptographicKey keyOriginal = objKdfProv.CreateKey(buffSecret);

    // Derive a key based on the original key and the derivation parameters.
    IBuffer keyDerived = CryptographicEngine.DeriveKeyMaterial(
        keyOriginal,
        pbkdf2Params,
        targetSize);

    // Encode the key to a hexadecimal value (for display)
    String strKeyHex = CryptographicBuffer.EncodeToHexString(keyDerived);

    // Return the encoded string
    return strKeyHex;
}

关于c# - 如何在 UWP c# 中散列和/或加盐密码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40474280/

相关文章:

c# - Xamarin Forms Visual Studio 2015 HttpClient 请求在 iOS 上不起作用

c# - 接口(interface)——有什么意义?

javascript - jquery推送自定义历史记录

Meteor,为什么散列后相同的密码,不同的字符串存储在数据库中

windows - 是否可以防止在 LOB UWP 桌面应用程序/后台任务中挂起?

c# - Entity Framework 代码优先 : Custom Mapping Using Attribute?

c# - WMV 流媒体文件大小限制

带有散列引用的 Python minidom 和 UTF-8 编码的 XML

windows - UWP 中用于 Xamarin Forms 项目的 AES 加密

windows - 有没有更好的方法从控制台应用程序启动 UWP 应用程序