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

如果我理解正确,这是为了保持纯文本内存不足,这样的应用程序是安全的反对内存,垃圾堆或内存分页到磁盘的深奥攻击。 SecureString提供非托pipe字节,并在一次消耗一个非托pipe字节 – 然后该string从内存中删除。 (如果我离开,纠正我!)

在ASP.NET中,秘密被收集在一个Web表单中,并以HTTPS的forms发回。 但是,然后Request对象将表单中的所有请求值转换为名称值对,并将它们放在一个集合中,例如Request [“TxtPassword”] – 因此,即使在我得到string之前,它已经被不安全地写入内存。 更糟的是,如果我使用的是控件,那么不安全的表示将在TextBox的属性中有更多的托pipestring。

对这个SecureString做任何事我需要一个接受非托pipestring的API – 所以看来我不能使用安全string存储proc参数或其他许多。

我这样做是错误的,还是试图使用SecureString而不是将不安全string的副本泄露到托pipe内存中是一个愚蠢的错误?

切换到OAuth或Windows身份validation不是一个选项。

正如您已经正确推断的,以及其他人已经提到的,使用SecureString来存储来自ASP.NET表单的安全性敏感数据是没有意义的,因为这些数据已经以纯文本的forms存在于内存中。

但是,还有其他一些场景,build议使用SecureString ,因为敏感数据是由程序本身创build的,在完成处理之后不应该保留在内存中。 例如,以编程方式创buildSharePoint网站,或将身份validation凭据从一个系统传输到另一个系统。

早在过去,保证敏感数据的使用寿命就越简单越容易。 它可以在堆栈中分配,并在程序完成后立即清除:

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

但是,托pipestring不可能实现这种方法,主要是因为:

  • 他们没有分配在堆栈上,
  • 它们是不变的,所以它们不能被清除,
  • 它们不是一次性的,所以不能保证GC能够释放数据的时间。 它甚至可能永远不会被释放,这取决于内存条件。

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

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

我认为你有它的基础知识。 SecureString是从客户端的angular度devise的。 所以对于一个WPF / Winforms应用程序(也许Silverlight,不记得它是否在那里),这是值得吨,而服务器端的应用程序,而不是由于不是第一个处理string。

SecureString最适合用于为系统间直接呼叫分配networking凭证。 这是在networking舞台上给出的,如果证书通过networking进入明文,但是如果你必须通过标准证书调用(ftp,目录服务等)发回证书,那么使用SecureString可以做到不作为一种过度的方法伤害。 虽然你是正确的,string已经在你的服务器系统上以纯文本,你至less可以减less系统之间的足迹。 如果你只是在本地使用这个密码,那么我会同意SecureString可能不是非常必要的。

但是,良好的安全习惯永远不会浪费时间。

在执行安全代码审查时,我唯一标记缺less使用SecureString地方是在数据可能被应用程序encryption并重用的情况下。

例如,当网站后端需要与第三方或需要凭证的其他内部资源通信时。 由于这些不能被散列,所以在需要构build请求时(也应该在TLS上),我会使用SecureString

另一种方法是尽可能使用Windows数据保护API 。

请注意, SecureString的目的是将内容保留在内存中的时间尽可能短。

如果我没有弄错,可以使用下面的解决scheme来避免inputCLR的stringpipe理: Web API:如何使用MultipartMemoryStreamProvider访问多部分表单值?

只读取ReadAsByteArrayAsync()中的ExecutePostProcessingAsync(..)方法中的FormData,它永远不会成为一个string。

你仍然需要https来保证input的安全。