c# - 在 ASP.NET 中使用 SecureString 有什么好处吗?

标签 c# asp.net securestring

如果我理解正确的话,这是为了将纯文本保留在内存之外,这样应用程序就可以安全地抵御对内存、垃圾堆或分页到磁盘的内存的深奥攻击。向 SecureString 提供非托管字节并一次消耗一个非托管字节——然后从内存中删除该字符串。 (如果我跑题了请纠正我!)

在 ASP.NET 中, secret 收集在网络表单中,该表单以 HTTPS 回传。但是随后 Request 对象将表单中的所有请求值转换为名称值对并将它们放入一个集合中,例如Request["TxtPassword"]-- 所以甚至在我能得到字符串之前,它已经被不安全地写入内存。更糟糕的是,如果我使用的是控件,那么不安全的表示形式将在 TextBox 的属性中包含更多托管字符串。

要使用此 SecureString 执行任何操作,我需要一个采用非托管字符串的 API——因此我似乎无法将安全字符串用于存储的 proc 参数或其他许多内容。

我这样做是错误的还是尝试使用 SecureString 并且不将不安全字符串的副本泄漏到托管内存中是愚蠢的差事?

切换到 OAuth 或 Windows 身份验证不是一种选择。

最佳答案

正如您正确推断和其他人已经提到的那样,使用 SecureString 毫无意义存储来自 ASP.NET 表单的安全敏感数据,因为该数据已经以纯文本形式存在于内存中。

但是,在其他情况下,建议使用 SecureString,因为敏感数据是由程序本身创建的,在处理完后不应保留在内存中。例如,以编程方式创建 SharePoint 站点,或将身份验证凭据从一个系统传输到另一个系统。

在过去的美好时光里,确保敏感数据的生命周期尽可能短比较容易。它可以在堆栈上分配并在程序使用完后立即清除:

char secret[512];
generate_secret(secret, sizeof(secret));
do_something_with(secret);
memset(secret, 0, sizeof(secret));
// Secret data is now gone.

不过,这种方法对于托管字符串是不可能的,主要是因为:

  • 它们没有分配到堆栈上,
  • 它们是不可变的,因此无法清除,
  • 它们不是一次性的,因此无法保证 GC 释放数据的时间。根据内存条件,它甚至可能永远不会被释放。

SecureString 试图通过可变的和一次性的来解决这个问题,这允许一个人写:

using (SecureString secret = new SecureString()) {
    GenerateSecret(secret);
    secret.MakeReadOnly();
    DoSomethingWith(secret);
}
// Secret data is now gone.

关于c# - 在 ASP.NET 中使用 SecureString 有什么好处吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23775907/

相关文章:

c# - 将字符串转换为安全字符串

c# - Convert.ToDecimal(string) 和 Decimal.Parse(string) 之间的区别

c# - Entity Framework 重用连接

c# - 从共享点数据库中提取文件

powershell - 文件 "randomly"中的 SecureString 停止工作

C# 解密值和公共(public)类属性...有什么风险?

c# - 使用 asp.net mvc 进行依赖注入(inject)

asp.net - 为什么我的验证会在 MVC3 中发布之前对 get 请求触发?

c# - 无法构建 ASP.Net 容器

c# - 文本框值不保存