ini*_*are 8 c# encryption wpf securestring
我怎样才能获得byte[]相当于a SecureString(我从中得到的PasswordBox)?
我的目标是使用a将这些字节写入CryptoStream文件,并且Write该类的方法接受byte[]输入,因此我想将其转换SecureString为byte[]所以我可以使用a CryptoStream.
编辑:我不想使用,string因为它打败了一个点SecureString
Eri*_*oyd 10
假设你想要使用字节数组并在完成后立即删除它,你应该封装整个操作,以便它自己清理:
public static T Process<T>(this SecureString src, Func<byte[], T> func)
{
IntPtr bstr = IntPtr.Zero;
byte[] workArray = null;
GCHandle handle = GCHandle.Alloc(workArray, GCHandleType.Pinned);
try
{
/*** PLAINTEXT EXPOSURE BEGINS HERE ***/
bstr = Marshal.SecureStringToBSTR(src);
unsafe
{
byte* bstrBytes = (byte*)bstr;
workArray = new byte[src.Length * 2];
for (int i = 0; i < workArray.Length; i++)
workArray[i] = *bstrBytes++;
}
return func(workArray);
}
finally
{
if (workArray != null)
for (int i = 0; i < workArray.Length; i++)
workArray[i] = 0;
handle.Free();
if (bstr != IntPtr.Zero)
Marshal.ZeroFreeBSTR(bstr);
/*** PLAINTEXT EXPOSURE ENDS HERE ***/
}
}
Run Code Online (Sandbox Code Playgroud)
以下是用例的外观:
private byte[] GetHash(SecureString password)
{
using (var h = new SHA256Cng()) // or your hash of choice
{
return password.Process(h.ComputeHash);
}
}
Run Code Online (Sandbox Code Playgroud)
没有麻烦,没有大惊小怪,没有明文留在内存中.
请记住,传递给的字节数组func()包含明文的原始Unicode呈现,这对于大多数加密应用程序来说应该不是问题.
我修改了原来的答案来处理unicode
IntPtr unmanagedBytes = Marshal.SecureStringToGlobalAllocUnicode(password);
byte[] bValue = null;
try
{
byte* byteArray = (byte*)unmanagedBytes.GetPointer();
// Find the end of the string
byte* pEnd = byteArray;
char c='\0';
do
{
byte b1=*pEnd++;
byte b2=*pEnd++;
c = '\0';
c= (char)(b1 << 8);
c += (char)b2;
}while (c != '\0');
// Length is effectively the difference here (note we're 2 past end)
int length = (int)((pEnd - byteArray) - 2);
bValue = new byte[length];
for (int i=0;i<length;++i)
{
// Work with data in byte array as necessary, via pointers, here
bValue[i] = *(byteArray + i);
}
}
finally
{
// This will completely remove the data from memory
Marshal.ZeroFreeGlobalAllocUnicode(unmanagedBytes);
}
Run Code Online (Sandbox Code Playgroud)