如果我的假设是错误的,请随意纠正我,但让我解释为什么我问。
取自MSDN,一个SecureString:
表示应保密的文本。在使用时,文本会被加密以保护隐私,当不再需要时,会从计算机内存中删除。
我明白了,在系统上的SecureString中存储密码或其他私人信息是完全有意义的。字符串,因为您可以控制它实际存储在内存中的方式和时间,因为System。字符串:
is both immutable and, when no longer needed, cannot be programmatically scheduled for garbage collection; that is, the instance is read-only after it is created and it is not possible to predict when the instance will be deleted from computer memory. Consequently, if a String object contains sensitive information such as a password, credit card number, or personal data, there is a risk the information could be revealed after it is used because your application cannot delete the data from computer memory.
然而,对于GUI应用程序(例如ssh客户端),SecureString必须从System.String构建。所有文本控件都使用字符串作为其底层数据类型。
因此,这意味着每当用户按下一个键时,旧的字符串就会被丢弃,并构建一个新字符串来表示文本框内的值,即使使用密码掩码也是如此。我们无法控制何时或是否将这些值从内存中丢弃。
现在是时候登录到服务器了。你猜怎么着?您需要在连接上传递一个字符串进行身份验证。让我们把SecureString转换为System.String....现在我们在堆上有一个字符串,没有办法强制它进行垃圾收集(或将0写入缓冲区)。
我的观点是:无论你做什么,在某个地方,那个SecureString会被转换成一个系统。字符串,这意味着它至少在某个时候存在于堆上(没有任何垃圾收集的保证)。
我的观点不是:是否有方法可以避免向ssh连接发送字符串,或者避免让控件存储字符串(创建自定义控件)。对于这个问题,您可以将“ssh连接”替换为“登录表单”、“注册表单”、“支付表单”、“你要喂你的小狗但不是你的孩子的食物表单”等等。
So, at what point does using a SecureString actually become
practical?
Is it ever worth the extra development time to completely eradicate
the use of a System.String object?
Is the whole point of SecureString to simply reduce the amount of time a System.String is on the heap (reducing its risk of moving to a physical swap file)?
If an attacker already has the means for a heap inspection, then he most likely either (A) already has the means to read keystrokes, or (B) already physically has the machine... So would using a SecureString prevent him from getting to the data anyways?
Is this just "security through obscurity"?
如果我的问题问得太过分了,对不起,我只是被好奇心控制了。请随意回答我的任何或所有问题(或者告诉我我的假设是完全错误的)。:)
以下文本是从HP Fortify静态代码分析器复制的
文摘:
PassGenerator.cs中的PassString()方法以不安全的方式存储敏感数据(即以字符串形式存储),使得提取敏感数据成为可能
通过检查堆来获取数据。
Explanation:
Sensitive data (such as passwords, social security numbers, credit card numbers etc.) stored in memory can be leaked if it is
stored in a managed String object. String objects are not pinned, so the garbage collector can relocate these objects at will and
leave several copies in memory. These objects are not encrypted by default, so anyone who can read the process' memory will be
able to see the contents. Furthermore, if the process' memory gets swapped out to disk, the unencrypted contents of the string
will be written to a swap file. Lastly, since String objects are immutable, removing the value of a String from memory can only
be done by the CLR garbage collector. The garbage collector is not required to run unless the CLR is low on memory, so there is
no guarantee as to when garbage collection will take place. In the event of an application crash, a memory dump of the
application might reveal sensitive data.
建议:
将敏感数据存储在SecureString对象中,而不是存储在string等对象中。对象中存储其内容
在内存中始终保存加密格式。
正如您已经正确识别的那样,SecureString相对于string提供了一个特定的优势:确定性擦除。这一事实有两个问题:
As others have mentioned and as you have noticed by yourself, this isn't enough by itself. You have to make sure that every step of the process (including retrieval of input, construction of the string, usage, deletion, transportation, etc) happens without defeating the purpose of using SecureString. This means that you must be careful to never create a GC-managed immutable string or any other buffer that will store the sensitive information (or you'll have to keep track of that as well). In practice, this isn't always easy to achieve, because lots of APIs only offer a way to work with string, not SecureString. And even if you do manage to everything right...
SecureString protects against very specific kinds of attack (and for some of them, it's not even that reliable). For example, SecureString does allow you to shrink the time window in which an attacker can dump the memory of your process and successfully extract the sensitive information (again, as you correctly pointed out), but hoping that the window is too small for the attacker to take a snapshot of your memory isn't considered security at all.
那么,什么时候应该使用它呢?只有当您正在使用可以让您使用SecureString满足所有需求的东西时,即使这样,您仍然应该注意,这仅在特定情况下是安全的。