在WCF服务的内存中缓存明文密码

时间:2010-03-24 17:24:09

标签: c# wcf passwords asterisk

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

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

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

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

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

2 个答案:

答案 0 :(得分:2)

SecureString使用加密内存,因此这可能会提高每次自己进行哈希的性能。但您必须在您的环境中对其进行分析。

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

以下是我的建议: 考虑密码泄漏的后果 - 基本上,黑客拥有密码值多少钱($或$$$?)?如今,大多数安全问题都来自财务激励。相对而言,纯粹的破坏行为远远超过这些人。

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

另一方面,如果值很低并且有其他可能的漏洞利用(并且经常存在),那么你可以做出一个合理的论据,即黑客的时间不值得破坏服务器并转储存储器中。

祝你好运。

答案 1 :(得分:1)

  

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

只要从现在到永恒(或下一个补丁,永远是第一个),在ram中存储缓存密码就像普通文本一样。如果你在ram中存储整个密码数据库(比如你的持久存储太慢),我认为将它们存储为安全字符串会更好,但由于你只存储了几个密码最多1分钟,我认为没有问题。