How hash and / or salt passwords in UWP C #?

After many google searches, I really can’t understand how the hash passwords in C # UWP, I tried Bcrypt, but it is not available for RT. Any ideas how I can hash my passwords in UWP? This is my first application in UWP, so I thought everything would work as in WPF, it looks like I was wrong. I tried BCRYPT from Nugetstore, but nothing will work on UWP.

I just need an easy way to hash and / or salt the string and an easy way to verify the hash.

+4
source share
3 answers

Having tried all of the above answers (thanks a lot for the help), I decided to go with MD5 hashing even though I know its really very weak hashing and doesn't have salt that suits my need. I use my passwords in UWP with the following code:

private static string ComputeMD5(string str)
     { 
         var alg = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5); 
         IBuffer buff = CryptographicBuffer.ConvertStringToBinary(str, BinaryStringEncoding.Utf8); 
         var hashed = alg.HashData(buff); 
         var res = CryptographicBuffer.EncodeToHexString(hashed); 
         return res;
    }
+1
source

How about this approach ( using System.Security.Cryptography):

  • To store user passwords in a database in a way that cannot be retrieved, passwords must be hashed using a one-way hash algorithm such as SHA1

  • To do this, use RNGCryptoServiceProvider to create a random salt, add the salt to the password, hash it using the SHA1 CryptoServiceProvider class and save the resulting row in the database along with the salt

  • , , , .

:

  // 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

UPDATE 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;
}
+3

GitHub, , , SHA . MS PBKDF2 Rfc2898DeriveBytes ( home-brew) , BCrypt.

nuget, , UWP.

:

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 password by first loading it from database by username
string storedHash = _repository.GetUserPasswordHash(username);
bool isPasswordValid = false;
if (storedHash != null)
{
    isPasswordValid = simpleHash.Verify("Password123", storedHash);
}

P.S. , UWP- nuget, , , :)

0

Source: https://habr.com/ru/post/1660120/


All Articles