Hashing Passwords with Md5 or Sha-256 C#

which algorithm preferred for hashing passwords C#?

MD5:

In 1996, a flaw was found with the design of MD5, and while it was
not a clearly fatal weakness, cryptographers began recommending the
use of other algorithms, such as SHA-1—which has since been found to
be vulnerable as well.

SHA1:

In 2005, cryptanalysts found attacks on SHA-1 suggesting that the
algorithm might not be secure enough for ongoing use

SHA2 which SHA256 is a type of does not have a known vulnerability as of the moment of writing.

SHA256, SHA512, MD5 generates exactly the same hash for different files in C# .NET 6

After the await file.CopyToAsync(ms), the position of the memory stream is at its end. sha.ComputeHashAsync(strm) calculates the hash of the data after the current position, so basically that of an empty stream.

Try resetting the position of the stream to the start before the call to _CalculateChecksum:

MemoryStream ms = new MemoryStream();
await file.CopyToAsync(ms);
ms.Seek(0, SeekOrigin.Begin);
string hash = await _CalculateChecksum(ms);

Hash and salt passwords in C#

Actually this is kind of strange, with the string conversions - which the membership provider does to put them into config files. Hashes and salts are binary blobs, you don't need to convert them to strings unless you want to put them into text files.

In my book, Beginning ASP.NET Security, (oh finally, an excuse to pimp the book) I do the following

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

The salt generation is as the example in the question. You can convert text to byte arrays using Encoding.UTF8.GetBytes(string). If you must convert a hash to its string representation you can use Convert.ToBase64String and Convert.FromBase64String to convert it back.

You should note that you cannot use the equality operator on byte arrays, it checks references and so you should simply loop through both arrays checking each byte thus

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

Always use a new salt per password. Salts do not have to be kept secret and can be stored alongside the hash itself.

SHA1 vs md5 vs SHA256: which to use for a PHP login?

Neither. You should use bcrypt. The hashes you mention are all optimized to be quick and easy on hardware, and so cracking them share the same qualities. If you have no other choice, at least be sure to use a long salt and re-hash multiple times.

Using bcrypt in PHP 5.5+

PHP 5.5 offers new functions for password hashing. This is the recommend approach for password storage in modern web applications.

// Creating a hash
$hash = password_hash($password, PASSWORD_DEFAULT, ['cost' => 12]);
// If you omit the ['cost' => 12] part, it will default to 10

// Verifying the password against the stored hash
if (password_verify($password, $hash)) {
// Success! Log the user in here.
}

If you're using an older version of PHP you really should upgrade, but until you do you can use password_compat to expose this API.

Also, please let password_hash() generate the salt for you. It uses a CSPRNG.

Two caveats of bcrypt

  1. Bcrypt will silently truncate any password longer than 72 characters.
  2. Bcrypt will truncate after any NUL characters.

(Proof of Concept for both caveats here.)

You might be tempted to resolve the first caveat by pre-hashing your passwords before running them through bcrypt, but doing so can cause your application to run headfirst into the second.

Instead of writing your own scheme, use an existing library written and/or evaluated by security experts.

  • Zend\Crypt (part of Zend Framework) offers BcryptSha
  • PasswordLock is similar to BcryptSha but it also encrypts the bcrypt hashes with an authenticated encryption library.

TL;DR - Use bcrypt.

C# to node crypto hashing - md5 and sha256

.Net Framework - AES encryption uses a 256 bit key and CBC mode and PKCS7 padding by default.

The code to port is very simple to read, it just does this:

return

BASE64 (
AES_ENCRYPT (
password,
Key: SHA256(username),
IV: MD5(username)
)
)

The same can easily be achieved on Node.

const crypto = require('crypto');

const key = crypto.createHash('sha256').update('username', 'utf8').digest();
const iv = crypto.createHash('md5').update('username', 'utf8').digest();

const encryptor = crypto.createCipheriv("aes-256-cbc", key, iv);

var crypted = Buffer.concat([encryptor.update('password', 'utf8'), encryptor.final()]);

let base64data = crypted.toString('base64');

console.log(base64data);

How to hash a password

UPDATE: THIS ANSWER IS SERIOUSLY OUTDATED. Please use the recommendations from the https://stackoverflow.com/a/10402129/251311 instead.

You can either use

var md5 = new MD5CryptoServiceProvider();
var md5data = md5.ComputeHash(data);

or

var sha1 = new SHA1CryptoServiceProvider();
var sha1data = sha1.ComputeHash(data);

To get data as byte array you could use

var data = Encoding.ASCII.GetBytes(password);

and to get back string from md5data or sha1data

var hashedPassword = ASCIIEncoding.GetString(md5data);


Related Topics



Leave a reply



Submit