mFe*_*ein 15 c# c++ memory security string
众所周知,C#string非常不安全,它没有固定在RAM中,垃圾收集器可以移动它,复制它,在RAM中留下多个痕迹,RAM可以交换并作为要读取的文件提供,没有提到其他几个已知的事实.
为了缓解这一点,微软想出了这个SecureString.问题是:使用它的正确方法是什么?
我问这个,因为迟早你将不得不提取内部字符串.是的,SecureString确实允许我们char一次写一个并给我们一些其他的小用法,同时隐藏它的秘密,但有时我们需要整个字符串或类似的东西.到目前为止,我看到的所有实现string最终都使用常规,使用SecureString我认为(或希望)的提取和解密内容在某些情况下可以避免,即使它可能涉及一些复杂的代码来绕过.NET string.
在我的例子中,我使用一个名为BCrypt的密码哈希库.它使用常规string来计算哈希值,我认为这远非理想.我没有找到任何可以SecureString直接接受的库,所以我没有太多的选择但是使用它.
目前我运行的代码如下:
SecureString password; // This usually comes from a PasswordBox Property
IntPtr passwordBSTR = Marshal.SecureStringToBSTR(password);
string insecurePassword = Marshal.PtrToStringBSTR(passwordBSTR);
Marshal.ZeroFreeBSTR(passwordBSTR);
passwordBSTR = default(IntPtr);
password.Clear();
// Use the insecurePassword....usually as:
bool result = BCrypt.Net.BCrypt.Verify(insecurePassword, user.Password); // This hashes the provided password and compares it with another BCrypt hash.
insecureString = string.Empty; // hoping for the GC to act now, fingers crossed.
// use result and etc...
Run Code Online (Sandbox Code Playgroud)
这样,密码raw string将被复制多次以用于该BCrypt方法,并且可能在其中多次复制.
这让我想到了一些问题:
1 - 在内存管理方面,字符串是否BSTR像字符串一样C?它们是否固定在RAM中我可以操作它们并按照我认为合适的方式擦除它们,因此在C#中使用它们或使用C++代码进行互操作会更安全,因此我可以消除很多我的.NET string操作(如验证是否密码字符串是空格或空格,还是具有正确的长度或具有所需的密码强度)?
2 - 如果问题的#1答案为"是",那么我是否应该投入一些时间将BSTR字符串传递给互操作C++代码来计算它的散列并验证?
3 - 我的后期代码是正确的还是我在SecureString操作时遗漏了什么?
需要明确的是:我对这个问题的主要意图是评估是否应该将我的所有密码处理代码从C#(可能使用C++/CLI或interop)传递给C++,以实现比C#提供的更安全的代码.这个场景真的让我担心密码字符串散列是多个字符串将被创建和复制,用户的秘密信息散布在整个RAM中.
举个例子:我可以制作一个方法:
public string SecureHash(SecureString password)
Run Code Online (Sandbox Code Playgroud)
这个方法将提取SecureString值并将其作为BSTR字符串(或其他提取选项,老实说,我不知道它们之间的好处)传递给C++哈希方法,因此我们可以控制密码在内存中的所有位置.
我要求这没有重大的工作重构我的代码,最后发现它一无所获,因为我一直在SecureStrings错误地使用并且已经有了解决方案,或者有一种虚假的安全感,有时会发生这种情况,因为我不知道BSTR字符串是如何在内存或其他SecureStrings 提取选项(Unicode,ANSI等)中实现的.
我想说你的选择是:
您缺少对 SecureString 的正确处理(在“使用”或“尝试/最后”中)。
| 归档时间: |
|
| 查看次数: |
1841 次 |
| 最近记录: |