Я пытаюсь получить SecureString
в виде byte[]
, который я могу держать закрепленным GC, закодированным в формате UTF-8.Я добился успеха в этом, но с UTF-16 (кодировка по умолчанию), но я не могу понять, как выполнить преобразование кодировки без возможности GC создать управляемую копию данных где-то (данные должныбыть в безопасности).
Вот что у меня есть (Контекст: алгоритм для вычисления хэша SecureString)
public static byte[] Hash(this SecureString secureString, HashAlgorithm hashAlgorithm)
{
IntPtr bstr = Marshal.SecureStringToBSTR(secureString);
int length = Marshal.ReadInt32(bstr, -4);
var utf16Bytes = new byte[length];
GCHandle utf16BytesPin = GCHandle.Alloc(utf16Bytes, GCHandleType.Pinned);
byte[] utf8Bytes = null;
try
{
Marshal.Copy(bstr, utf16Bytes, 0, length);
Marshal.ZeroFreeBSTR(bstr);
// At this point I have the UTF-16 byte[] perfectly.
// The next line works at converting the encoding, but it does nothing
// to protect the data from being spread throughout memory.
utf8Bytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, utf16Bytes);
return hashAlgorithm.ComputeHash(utf8Bytes);
}
finally
{
if (utf8Bytes != null)
{
for (var i = 0; i < utf8Bytes.Length; i++)
{
utf8Bytes[i] = 0;
}
}
for (var i = 0; i < utf16Bytes.Length; i++)
{
utf16Bytes[i] = 0;
}
utf16BytesPin.Free();
}
}
Каков наилучший способ сделать это преобразование, и япытаясь сделать это в правильном месте, как у меня, или я должен сделать это как-то раньше?Может ли это быть более эффективным при использовании памяти, если полностью пропустить шаг UTF-16 byte []?