Re: Hash MD5, Sha1 and Length

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



On Sun, 13 Sep 2009 13:34:30 -0700 (PDT), shapper <mdmoura@xxxxxxxxx>
wrote:

Hello,

I tried to create the extension with and without salt and with
optional encoding.
Salt must always be present, either generated or retrieved form the
database. Reduce the number of options available, that way the users
have less chances of picking the wrong options.

I also made the salt as OUT so if the user does not provide a salt
value then it will be generated and updated.
Always generate the salt internally, the users never need to see it.
You generate it, you save it to the database and you retrieve it when
needed.

This is useful to save the Salt in a database.

1. Can the salt parameter be a String?
Unwise. A string encoding is not completely random and a salt should
be as random as possible.


Then inside the extension I would convert the salt to bytes[] or
create a random in bytes and at the end convert it to string.
I think it would be more user friendly.

2. What is the difference between using SHA256Managed() or
SHA256CryptoServiceProvider() ?
Pass.

Which one should I use?

Could someone, please, help me improve my code?
I am not so familiar with Cryptography ...

This is the code I have so far:

public static String Hash(this String value, HashType type) {
return Hash(value, type, new UTF8Encoding());
} // Hash

public static String Hash(this String value, HashType type,
Encoding encoding) {

// Hash value
HashAlgorithm algorithm;
switch (type) {
case HashType.MD5:
algorithm = new MD5CryptoServiceProvider();
break;
case HashType.SHA1:
algorithm = new SHA1CryptoServiceProvider();
break;
case HashType.SHA256:
algorithm = new SHA256CryptoServiceProvider();
break;
case HashType.SHA384:
algorithm = new SHA384CryptoServiceProvider();
break;
case HashType.SHA512:
algorithm = new SHA512CryptoServiceProvider();
break;
default:
throw new ArgumentException("Invalid hash type", "type");
}
Byte[] hash = algorithm.ComputeHash(encoding.GetBytes(value));
You need to stretch the calculation by repeating it many times.


return BitConverter.ToString(hash).Replace("-", String.Empty);

} // Hash
Do not allow the user to select the hash function. They can have any
hash function they want as long as it is SHA256.



public static String Hash(this String value, HashType type, out
Byte[] salt) {
return Hash(value, type, out salt, new UTF8Encoding());
} // Hash

public static String Hash(this String value, HashType type, out
Byte[] salt, Encoding encoding) {

// Check salt
if (salt == null) {

// Define a random salt
Random random = new Random();
Int32 size = random.Next(4, 8);
salt = new Byte[size];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetNonZeroBytes(salt);
This is needless complication again. Short salts are dangerous. Pick
a reasonable salt size and stick with it:

final static int SALT_SIZE = 16;
byte[] salt = new byte[SALT_SIZE];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(salt);

It is a minor error to use the GetNonZeroBytes() method in this
context as it reduces the randomness of the salt.


}

// Define salted
Byte[] valueBytes = encoding.GetBytes(value);
Byte[] valueSaltedBytes = new Byte[valueBytes.Length +
valueBytes.Length];
for (Int32 i = 0; i < valueBytes.Length; i++)
valueSaltedBytes[i] = valueBytes[i];
for (Int32 i = 0; i < salt.Length; i++)
valueSaltedBytes[valueBytes.Length + i] = salt[i];

// Hash value
HashAlgorithm algorithm;
switch (type) {
case HashType.MD5:
algorithm = new MD5CryptoServiceProvider();
break;
case HashType.SHA1:
algorithm = new SHA1CryptoServiceProvider();
break;
case HashType.SHA256:
algorithm = new SHA256CryptoServiceProvider();
break;
case HashType.SHA384:
algorithm = new SHA384CryptoServiceProvider();
break;
case HashType.SHA512:
algorithm = new SHA512CryptoServiceProvider();
break;
default:
throw new ArgumentException("Invalid hash type", "type");
}
Again, give the user no choice. SHA256 only.



// Define hash
Byte[] hash = algorithm.ComputeHash(valueSaltedBytes);
Byte[] hashSalted = new Byte[hash.Length + salt.Length];
for (Int32 i = 0; i < hash.Length; i++)
hashSalted[i] = hash[i];
for (Int32 i = 0; i < salt.Length; i++)
hashSalted[hash.Length + i] = salt[i];

// Return hash
return Convert.ToBase64String(hashSalted);
Base64 increases both processing time and the storage space needed.
Unless you need to transmit the data over a text-only link then stick
with byte arrays.

rossum


} // Hash

Thank You!
Miguel

.



Relevant Pages

  • Re: Hash MD5, Sha1 and Length
    ... I also made the salt as OUT so if the user does not provide a salt ... public static String Hash ... Encoding encoding) { ... algorithm = new MD5CryptoServiceProvider; ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Hash MD5, Sha1 and Length
    ... These are standard cryptographic methods for protecting bulk passwords ... algorithm = new MD5CryptoServiceProvider; ... The salt prevents two people using the same password having the same ... hash and also stops an attacker pre-calculating hashes for commonly ...
    (microsoft.public.dotnet.languages.csharp)
  • Re:encryption algs
    ... systems is a salted hash algorithm. ... A hash is a numerical value of fixed length which unequivocally ... The intention behind a Salted Hash is to have this type of attack fail ... and only then compute the hash over password and salt. ...
    (Security-Basics)
  • Re: Hashed PWs more secure than encrypted PWs?
    ... >> If the salt is different, ... MD5 is a message-digest algorithm, ... >this way as opposed to DES? ...
    (comp.security.unix)
  • Re: Hashed PWs more secure than encrypted PWs?
    ... >> If the salt is different, ... MD5 is a message-digest algorithm, ... >this way as opposed to DES? ...
    (comp.security.unix)