如果我的假设在这里错误,请随时纠正我,但是让我解释为什么我要问。
取自MSDN,是SecureString
:
表示应保密的文本。文本在使用时经过加密以确保隐私,在不再需要时从计算机内存中删除。
我明白了,将密码或其他私人信息存储在SecureString
上方是完全有意义的System.String
,因为您可以控制将密码和其他私人信息实际存储在内存中的方式和时间,因为System.String
:
既是不可变的,并且在不再需要时不能以编程方式安排进行垃圾回收;也就是说,实例在创建后是只读的,无法预测何时将实例从计算机内存中删除。因此,如果String对象包含敏感信息,例如密码,信用卡号或个人数据,则使用该信息后可能会泄露该信息,因为您的应用程序无法从计算机内存中删除数据。
但是,对于GUI应用程序(例如ssh客户端),SecureString
必须从构建 System.String
。所有的文本控件都使用字符串作为其基础数据类型。
因此,这意味着即使用户使用密码掩码,每次用户按下一个键时,旧的字符串都会被丢弃,而新的字符串将被构建以表示文本框内的值。而且我们无法控制何时或是否从内存中丢弃这些值中的任何一个。
现在该登录服务器了。你猜怎么了?您需要在连接上传递字符串以进行身份验证。因此,让我们将其SecureString
转换为System.String
....现在堆上有一个字符串,无法强制其通过垃圾回收(或将0写入其缓冲区)。
我的观点是:无论您做什么,SecureString
都将被转换为System.String
,这意味着它至少会在某个时刻存在于堆中(不保证任何垃圾回收)。
我的意思不是:是否有某种方法可以绕过向ssh连接发送字符串,或者可以避免使控件存储字符串(创建自定义控件)。对于这个问题,您可以将“ ssh连接”替换为“登录表格”,“注册表格”,“付款表格”,“您要喂养的食物,而不是您的孩子的食物”,等等
- 那么,在什么时候使用
SecureString
实际可行呢? - 完全消除
System.String
对象的使用是否值得花费额外的开发时间? SecureString
仅仅是为了减少aSystem.String
在堆上的时间(降低其移至物理交换文件的风险)的全部意义?- 如果攻击者已经具有检查堆的方法,那么他很可能要么(A)已经具有读取击键的方法,要么(B)已经物理上拥有了机器 ……因此可以使用
SecureString
防止他进入的方法。反正数据? - 这仅仅是“默默无闻的安全”吗?
抱歉,如果我把问题放在太深的地方,好奇心会变得更好。随时回答我的任何或所有问题(或告诉我我的假设完全错误)。:)
SecureString
并不是真正的安全字符串。这只是减少时间窗口的一种方法,人们可以在该时间窗口中检查您的内存并成功获取敏感数据。这不是防弹,也不是故意的。但是您提出的观点非常有效。相关:stackoverflow.com/questions/14449579/...