乍一看,这可能听起来很糟糕,但这是我的场景:我有一个 Windows 服务,它使用用户名身份验证公开多个 WCF 端点。自定义身份验证器将在本地数据库中查找用户的凭据(密码存储为加盐 SHA-1),或者它将向另一个服务发出 WCF 请求以验证密码。(用户对象上有一个可以是内部或外部的枚举,指示要使用哪个身份验证源)。
我发现对我的服务的每个请求都执行查找+哈希检查或进行 WCF 调用的成本很高,因此我想缓存用户名/密码信息。缓存中的每个项目都有一个生命周期,例如,如果缓存中的项目存在 60 秒,则在下一次请求时,身份验证器将根据原始源而不是缓存验证凭据,然后对其进行更新。
对于本地数据库,我可以简单地将用户名/SHA1 对存储在字典中,对于来自“内部”用户的每个请求,我只需重新散列提供的密码并进行比较。对于“外部”用户,我只会将明文密码提交给身份验证器,因此我可以对其进行哈希处理并将其存储为缓存的一部分。尽管这无疑为我节省了数据库请求或远程服务调用的开销,但我仍然必须每次都执行散列操作。
有问题的服务将在具有良好物理和网络安全性的内部服务器上运行。将明文密码存储在缓存中而不是存储散列版本是否可以接受?在这种情况下,我的风险似乎是攻击者转储进程的内存并获取密码。如果我认为这种风险是可以接受的,是否还有其他原因我应该避免将明文密码存储在内存中?
如果我选择使用明文密码,我认为 SecureString 可以在一定程度上限制我的风险。使用 SecureString 是否值得麻烦(实现它似乎很迂回)?我很清楚持久存储未散列的密码的风险,但是我不确定对明文密码的易失性存储的共识似乎是什么。