Thursday, August 10, 2006

.Net 2.0: Hash with Salt using SecureString

Cryptography Simplified in Microsoft .NET
Security Guidelines: .NET Framework 2.0

Ideally, we would return a SecureString here and make the consuming developer work with that but for our example...

public string HashInput(string input, int saltLength)
{
byte[] ssBytes;

// create salt
byte[] bytSalt = new byte[saltLength];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(bytSalt);

// create secure string for concatinating input and salt
using (SecureString ss = new SecureString())
{
// append original string
foreach (char c in input.ToCharArray())
{
ss.AppendChar(c);
}

// append salt
foreach (byte b in bytSalt)
{
ss.AppendChar(Convert.ToChar(b));
}

// prevent SecureString manipulation
ss.MakeReadOnly();

// instantiate hash provider
SHA512Managed sha = new SHA512Managed();

// pointer to hold unmanaged reference to SecureString instance
IntPtr bstr = IntPtr.Zero;

try
{
// marshall SecureString into byte array
ssBytes = new byte[ss.Length * 2];
Marshal.Copy((bstr = Marshal.SecureStringToBSTR(ss)),
ssBytes, 0, ssBytes.Length);
}
finally
{
// Make sure that the clear text data is zeroed out
Marshal.ZeroFreeBSTR(bstr);
}

// hash byte array
byte[] hashed = sha.ComputeHash(ssBytes);

// clear the provider memory
sha.Clear();

return Convert.ToBase64String(hashed);
}
}

No comments: