What's the size of unmanaged buffer from SecureString?

Trips

Well-known member
Joined
Aug 7, 2010
Messages
2,788
Hi,
Im trying to make proper use of the SecureString class to handle passwords that need to be stored on the database and which will be later used for authenticating users. For such an scenario, I understand that the best practice is to store a salted hash
of the password and later compare hashes when authenticating.
So, Ive come up with the following class for hashing the passwords:

<div style="color:Black;background-color:White; <pre>
<span style="color:Blue; using System;
<span style="color:Blue; using System.IO;
<span style="color:Blue; using System.Runtime.InteropServices;
<span style="color:Blue; using System.Security;
<span style="color:Blue; using System.Security.Cryptography;

<span style="color:Blue; public <span style="color:Blue; class PasswordHasher
{

<span style="color:Blue; private <span style="color:Blue; readonly HashAlgorithm _hashAlgorithm;

<span style="color:Blue; public PasswordHasher(HashAlgorithm hashAlgorithm)
{
<span style="color:Blue; if (hashAlgorithm == <span style="color:Blue; null)
<span style="color:Blue; throw <span style="color:Blue; new ArgumentNullException(<span style="color:#A31515; "hashAlgorithm");

_hashAlgorithm = hashAlgorithm;
}

<span style="color:Blue; public <span style="color:Blue; byte[] ComputeHash(SecureString password, <span style="color:Blue; string salt)
{
<span style="color:Blue; if (password == <span style="color:Blue; null)
<span style="color:Blue; throw <span style="color:Blue; new ArgumentNullException(<span style="color:#A31515; "password");

<span style="color:Blue; if (salt == <span style="color:Blue; null)
<span style="color:Blue; throw <span style="color:Blue; new ArgumentNullException(<span style="color:#A31515; "salt");

<span style="color:Blue; using (<span style="color:Blue; var passwordCopy = password.Copy())
{
AddSalt(passwordCopy, salt);
<span style="color:Blue; return ComputeHash(passwordCopy);
}
}

<span style="color:Blue; private <span style="color:Blue; void AddSalt(SecureString password, <span style="color:Blue; string salt)
{
<span style="color:Blue; foreach (<span style="color:Blue; var c <span style="color:Blue; in salt)
password.AppendChar(c);

password.MakeReadOnly();
}

<span style="color:Blue; private <span style="color:Blue; byte[] ComputeHash(SecureString password)
{
IntPtr ptr = Marshal.SecureStringToGlobalAllocUnicode(password);
<span style="color:Blue; try
{
<span style="color:Blue; int sizeInBytes = password.Length * <span style="color:Blue; sizeof(<span style="color:Blue; char);
<span style="color:Blue; return UnsafeComputeHash(ptr, sizeInBytes);
}
<span style="color:Blue; finally
{
Marshal.ZeroFreeGlobalAllocUnicode(ptr);
}
}

<span style="color:Blue; unsafe <span style="color:Blue; private <span style="color:Blue; byte[] UnsafeComputeHash(IntPtr memoryPointer, <span style="color:Blue; int sizeInBytes)
{
<span style="color:Blue; using (<span style="color:Blue; var stream = <span style="color:Blue; new UnmanagedMemoryStream((<span style="color:Blue; byte*)memoryPointer.ToPointer(), sizeInBytes))
<span style="color:Blue; return _hashAlgorithm.ComputeHash(stream);
}

}

[/code]
But I feel like making a leap of faith when deciding that the size of the unmanaged memory buffer is exactly
password.Length * sizeof(char) and then passing that value as the
sizeInBytes parameter of the UnsafeComputeHash . Ive tested the class and it appears to be working fine, but I wanted to be sure Im not risking to make any illegal access to memory under any circumstances.
Does anyone knows how to be sure of the size of the unmanaged memory buffer that is being allocated by
Marshal.SecureStringToGlobalAllocUnicode ?
Thanks in advance.

View the full article
 
Back
Top