C# 使用SecureString的配置是否真正安全?

C# 使用SecureString的配置是否真正安全?,c#,.net-core,C#,.net Core,在我的一次代码审查中,我偶然发现了一个有趣的SecureString实现。从逻辑上讲,在内存中隐藏值是有好处的,但我对IConfiguration的理解是,当通过ConfigurationBuilder注入和构建时,内存中已经存在一个副本供使用。因此,SecureString虽然隐藏了明文值,但配置访问会自动否定密码文本 如果我的想法是正确的,那么该值实际上是不安全的,甚至不应该使用SecureString,因为它一开始就不安全- public class Sample { priva

在我的一次代码审查中,我偶然发现了一个有趣的
SecureString
实现。从逻辑上讲,在内存中隐藏值是有好处的,但我对
IConfiguration
的理解是,当通过
ConfigurationBuilder
注入和构建时,内存中已经存在一个副本供使用。因此,
SecureString
虽然隐藏了明文值,但配置访问会自动否定密码文本

如果我的想法是正确的,那么该值实际上是不安全的,甚至不应该使用
SecureString
,因为它一开始就不安全-

public class Sample
{
     private readonly SecureString secret;
     public Sample(IConfiguration configuration) => secret = new NetworkCredentials(String.Empty,
          configuration.GetSection("Api:Credentials")["secret"]).SecurePassword;
}

文档中基本上提到了:

总的来说,SecureString比String更安全,因为它限制了敏感字符串数据的暴露。但是,这些字符串仍可能暴露于任何可以访问原始内存的进程或操作,例如主机上运行的恶意进程、进程转储或用户可查看的交换文件。建议的替代方法不是使用SecureString保护密码,而是对存储在进程外部的凭据使用不透明句柄

在某些平台上甚至没有实现。在.net框架中,它甚至在某个时候变成了字符串,那么为什么它会出现呢?使用它有意义吗

关于你的评论:

如果我的想法是正确的,那么这个值实际上是不安全的,甚至不应该使用SecureString,因为它一开始就不安全-

使用它是有意义的。考虑值100%的安全性是没有意义的,它只是增加了一层安全性。 它确实限制了暴露,这是我们在安全编码时应该努力做到的

在下面这个极好的答案中可以找到一些使用它的完全合理的理由:


我能想到的另一个场景是:如果您使用某种远程密钥存储,例如,使用它更有意义。

SecureString
多年来一直被认为不安全;坦白地说,没有任何意义的攻击向量会保护你不受攻击;请参阅此处的“备注”(以及链接的github帖子):@MarcGravell这就是我所想的,我试图弄清楚编写本文的开发人员为什么会这样做。这些值通过配置以明文形式存在,那么为什么要实现呢?请记住,配置可能不是磁盘上的文件(环境变量),也可能是磁盘上的文件,但不是存储在源代码管理中的文件(与执行机密的方式相同)。如果配置文件中仍然以明文形式存在,这一点帮助都没有。如果他们可以访问服务器的内存,他们可能也可以访问硬盘,在这种情况下,他们可以只读取配置文件。@EJoshuaS配置来自多个源,而不仅仅是一个文件。Azure密钥库和Azure配置作为软件包提供,而磁盘本身可以加密。或者,可以使用存储在密钥库中的密钥对设置文件进行加密。这就是说,密钥库提供商本身不使用SecureString,但Microsoft表示:“我们不建议您在新开发中使用SecureString类。有关更多信息,请参阅SecureString不应在GitHub上使用。”我明白了。但是既然您已经基于配置文件,那么为什么不添加额外的层呢?如果您可以通过各种方式将解决方案移植到基于证书的身份验证,请这样做。不这样做的唯一原因是,它可能会产生错误的安全感。感谢您的反馈,感谢您的澄清。