How to use SHA-512 with Rfc2898DeriveBytes in my salt and hash code?

I am completely new to cryptography, but learning. I have compiled many different suggestions from my research on the Internet and made my own class for handling hash, salt, key stretching and comparing / converting related data.

After exploring the .NET built-in cryptography library, I found that I only have SHA-1. But I come to the conclusion that this is not bad, since I use several iterations of the hash process. It is right?

But if I wanted to start with a more robust SHA-512, how could I implement it in my code below? Thanks in advance.

using System; using System.Runtime.InteropServices; using System.Security; using System.Security.Cryptography; public class CryptoSaltAndHash { private string strHash; private string strSalt; public const int SaltSizeInBytes = 128; public const int HashSizeInBytes = 1024; public const int Iterations = 3000; public string Hash { get { return strHash; } } public string Salt { get { return strSalt; } } public CryptoSaltAndHash(SecureString ThisPassword) { byte[] bytesSalt = new byte[SaltSizeInBytes]; using (RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider()) { crypto.GetBytes(bytesSalt); } strSalt = Convert.ToBase64String(bytesSalt); strHash = ComputeHash(strSalt, ThisPassword); } public static string ComputeHash(string ThisSalt, SecureString ThisPassword) { byte[] bytesSalt = Convert.FromBase64String(ThisSalt); Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes( convertSecureStringToString(ThisPassword), bytesSalt, Iterations); using (pbkdf2) { return Convert.ToBase64String(pbkdf2.GetBytes(HashSizeInBytes)); } } public static bool Verify(string ThisSalt, string ThisHash, SecureString ThisPassword) { if (slowEquals(getBytes(ThisHash), getBytes(ComputeHash(ThisSalt, ThisPassword)))) { return true; } return false; } private static string convertSecureStringToString(SecureString MySecureString) { IntPtr ptr = IntPtr.Zero; try { ptr = Marshal.SecureStringToGlobalAllocUnicode(MySecureString); return Marshal.PtrToStringUni(ptr); } finally { Marshal.ZeroFreeGlobalAllocUnicode(ptr); } } private static bool slowEquals(byte[] A, byte[] B) { int intDiff = A.Length ^ B.Length; for (int i = 0; i < A.Length && i < B.Length; i++) { intDiff |= A[i] ^ B[i]; } return intDiff == 0; } private static byte[] getBytes(string MyString) { byte[] b = new byte[MyString.Length * sizeof(char)]; System.Buffer.BlockCopy(MyString.ToCharArray(), 0, b, 0, b.Length); return b; } } 

Notes. I referred to many practices from https://crackstation.net/hashing-security.htm . The slowEquals comparison method is to normalize runtime by preventing branching. Using SecureString is to have an encrypted form of password pass between this class and other classes and pages in my web application. Although this site will depend on HTTPS, itโ€™s always nice to go the extra mile to ensure security as much as possible, although itโ€™s within reason.

In my code, I set the key string to 128 bytes (although sometimes it increases, which is great), the hash size is up to 1 KB and the number of iterations is 3000. This is slightly larger than the typical 64-byte salt, 512-byte hash and 1000 or 2 000 iterations, but then again the input speed and application performance are extremely low.

Thoughts?

+6
source share
3 answers

Answering a question: download free code samples from " SecurityDriven.NET ". Find the PBKDF2 class that accepts the HMAC factory. HMACSHA512 factory is available, among others.

Since you are new to cryptography, I also strongly recommend that you read the book (for example, to fully understand the points that CodesInChaos made).

+5
source
  • 3000 iterations are pretty low. Even 10,000 is low. But you need to increase the security gain of additional iterations against the risk that an attacker runs a DoS server on your server, often tries to log in, which causes an expensive hash for each attempt.
  • There are more than 128 bits / 16 bytes in salt. Salt must be unique, nothing more.
  • A hash larger than its own size (20 bytes for SHA-1) reduces performance for the defender, but not for the attacker. Since this means that you can allow fewer iterations, it actually weakens security.

    For example, at the same cost as your hash with 1024 bytes with 3000 iterations, you can afford a 20-byte hash with 156000 iterations, which is 52 times more expensive than a crack.

  • To use SHA-2, you will need a completely different implementation of PBKDF2, one of which is included in .net, hard-coded to use SHA-1.

    If you bothered to use a third-party library, I would prefer to use the bcrypt library, as it is much stronger against GPU-based attackers.

  • Your API is embarrassing to use, because you push the salt control to the caller, rather than processing it in the Create / Verify functions.

  • It's stupid to use SecureString and then convert it to String . This primarily prevents the entire point of using a SecureString .

    Personally, I would not worry about SecureString in a typical application. This is useful if you combine it with an extensive security overview of the whole stack, which checks that the password is never stored in String and is always deleted from the mutable storage as soon as it is no longer needed.

  • I would not store passwords / salts in instance variables. Just keep them local in their respective functions. I would save the configuration in instance variables (e.g. number of iterations).

  • While SHA-1 is weakened cryptographically, attacks lead to collisions. For password hashing, conflicts are irrelevant, and your preliminary attacks are what you need. SHA-1 is still pretty strong in this regard.

    The main advantage of the SHA-512 is not that it is cryptographically stronger (although it is), that the 64-bit arithmetic costs the attacker more than the defender, since the defender is likely to use the Intel 64-bit processor, which offers fast 64 bit arithmetic.

+8
source

If anyone comes across this question by searching, now Microsoft is providing Microsoft.AspNetCore.Cryptography.KeyDerivation a NuGet package that allows you to use PBKDF2 with SHA-256 and SHA-512 hash functions. Documentation can be found at docs.microsoft.com .

+1
source

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


All Articles