2

乍一看,这可能听起来很糟糕,但这是我的场景:我有一个 Windows 服务,它使用用户名身份验证公开多个 WCF 端点。自定义身份验证器将在本地数据库中查找用户的凭据(密码存储为加盐 SHA-1),或者它将向另一个服务发出 WCF 请求以验证密码。(用户对象上有一个可以是内部或外部的枚举,指示要使用哪个身份验证源)。

我发现对我的服务的每个请求都执行查找+哈希检查或进行 WCF 调用的成本很高,因此我想缓存用户名/密码信息。缓存中的每个项目都有一个生命周期,例如,如果缓存中的项目存在 60 秒,则在下一次请求时,身份验证器将根据原始源而不是缓存验证凭据,然后对其进行更新。

对于本地数据库,我可以简单地将用户名/SHA1 对存储在字典中,对于来自“内部”用户的每个请求,我只需重新散列提供的密码并进行比较。对于“外部”用户,我只会将明文密码提交给身份验证器,因此我可以对其进行哈希处理并将其存储为缓存的一部分。尽管这无疑为我节省了数据库请求或远程服务调用的开销,但我仍然必须每次都执行散列操作。

有问题的服务将在具有良好物理和网络安全性的内部服务器上运行。将明文密码存储在缓存中而不是存储散列版本是否可以接受?在这种情况下,我的风险似乎是攻击者转储进程的内存并获取密码。如果我认为这种风险是可以接受的,是否还有其他原因我应该避免将明文密码存储在内存中?

如果我选择使用明文密码,我认为 SecureString 可以在一定程度上限制我的风险。使用 SecureString 是否值得麻烦(实现它似乎很迂回)?我很清楚持久存储未散列的密码的风险,但是我不确定对明文密码的易失性存储的共识似乎是什么。

4

2 回答 2

2

SecureString 使用加密内存,因此与每次自己进行散列相比,这可能会提高性能。但是您必须在您的环境中对其进行概要分析。

至于将普通密码存储在内存中的风险,这不是在这种情况下可以回答的问题。我只能说,是的,没关系。因为是针对我的情况,各种原因。但那和你的不一样。

以下是我的建议:考虑一下密码泄露的后果——基本上,对于黑客来说,拥有一个密码会值多少钱($ 或 $$$?)?如今,大多数安全问题都来自经济激励。相对而言,纯粹的破坏行为被这些家伙超越了。

现在将其与以完全不同的方式破坏安全性的可能性进行比较,即 SQL 注入或打电话给用户“验证他们的帐户”。如果几个密码的 $ 值很高并且没有其他方法可以获取它们,那么也许你应该继续加密它们(现在你已经证明了购买更强大的服务器的成本是合理的!)。并确保您随后保护加密密钥——一旦黑客拥有您的服务器,这些密钥很可能与程序内存一样容易访问。

另一方面,如果该值较低并且有其他可能的漏洞现成可用(并且经常有),您可以合理地论证黑客不值得花时间破坏服务器并转储内存。

祝你好运。

于 2010-03-24T17:34:27.293 回答
1

有问题的服务将在具有良好物理和网络安全性的内部服务器上运行。

只要从现在到永恒(或下一个补丁,哪个先出现)都是如此,将缓存的密码作为纯文本存储在 ram 中就可以了。如果您将整个密码数据库存储在 ram 中(假设您的持久存储太慢),我认为将它们存储为安全字符串会更好,但由于您最多只存储几个密码 1 分钟,我认为没有问题。

于 2010-03-24T17:35:16.653 回答