非常密切相关:如何在没有SecureString的情况下保护字符串?
同样密切相关的还有:我什么时候需要.NET中的SecureString?
非常密切相关(OP正在努力实现一些非常相似的东西):C#&WPF-将SecureString用于客户端HTTP API密码
.NET Framework有一个名为SecureString的类。然而,即使是微软也不再建议将其用于新的开发。根据第一个链接的问答;A、 至少有一个原因是,字符串将以明文形式在内存中至少一段的时间(即使时间很短)。至少有一个答案也扩展了这样一个论点,即如果他们无论如何都可以访问服务器的内存,那么在实践中,安全性可能无论如何都会被破坏,所以这对你没有帮助。(第二个链接的问答暗示,甚至有人讨论过将其从.NET Core中完全删除)。
话虽如此,微软关于SecureString
的文档并不建议更换,而关于链接问答的共识是:;A似乎是这样的衡量标准无论如何都不会是有用的。
我的应用程序是一个ASP.NET核心应用程序,它使用HttpClient
类广泛使用对外部供应商的API调用。对于HttpClient
,通常建议的最佳实践是使用单个实例,而不是为每个调用创建一个新实例。
但是,我们的供应商要求所有API调用都包含我们的API密钥作为具有特定名称的头。我目前安全地存储密钥,在Startup.cs
中检索它,并将它添加到HttpClient
实例的头中。
不幸的是,这意味着我的API密钥将在应用程序的整个生命周期中以明文形式保存在内存中。我发现这对于服务器上的web应用程序来说尤其麻烦;尽管服务器由公司IT维护,但我一直被教导要将公司网络视为半敌对环境,在这种情况下不要纯粹依赖公司防火墙来实现应用程序安全。
对于这种情况,微软有推荐的最佳实践吗?这是否是他们反对使用SecureString
的建议的潜在例外?(具体如何运作是另一个问题)。或者另一个问题的答案是什么;我不应该担心像这样存在于内存中的明文字符串,这句话真的很正确吗?
注意:根据对此问题的回答,我可能会发布一个后续问题,询问是否可以将类似SecureString
的内容作为HttpClient
标头的一部分。或者我必须做一些棘手的事情,比如在使用之前填充标题,然后在使用之后将其从内存中删除?(不过,这会给并发调用带来一场噩梦)。如果人们认为我应该做这样的事情,我很乐意为此提出一个新的问题。
你太偏执了。
首先,如果黑客获得了你的网络服务器的root访问权限,你会遇到比你的超级机密网络应用程序凭据被盗更大的问题。越来越大的问题。一旦黑客站在你这一边,游戏就结束了。
其次,一旦你的infosec团队检测到入侵(如果他们没有检测到,那么你又遇到了更大的问题),他们会告诉你,你要做的第一件事就是更改你所知道的每一个密钥和密码。
第三,如果黑客确实获得了对你的网络服务器的root访问权限,他们的第一个想法不会是"让我们转储内存以供稍后分析"。转储文件相当大(通过网络传输需要时间,网络流量很可能会被注意到),并且(至少在Windows上)挂起进程直到它完成(所以你会注意到你的网络应用程序没有响应),这两种情况都可能引发一些危险信号。
不,黑客在那里是为了在最短的时间内获取尽可能多的有价值的信息,因为他们知道自己的访问随时都可能被发现。因此,他们将首先追求唾手可得的成果——用户名和密码。然后,他们将继续尝试找出连接到该服务器的内容,由于您的数据库凭据可能在该服务器上的配置文件中,他们几乎肯定会将注意力转移到更有趣的目标上。
因此,综合考虑,你的API密钥极不可能被泄露-即使是这样,也不会因为你做了什么或没有做什么。有比试图确保已经(或应该)非常安全的东西更有效的方法来集中你的时间。最后,无论你设置了多少层安全措施。。。在某个阶段,API或SSL密钥将在内存中是原始的。