PasswordDerivedKey
函数生成的密钥,通过传递密码和12字节的盐。我已经在应用程序代码中实现了逻辑,“密码”是登录用户的用户名,“盐”是静态字节数组。最佳的存储密码和盐的方式是什么,因为有人可以轻松确定盐(通过反射我的代码)和一个人的用户名。
我可以采用哪些替代方案来安全地存储密码和盐。我不认为将它们存储在我的应用程序代码中是最好的方法。
编辑:通过密码,我指的是PBKDF函数中使用的密码(用于派生加密密钥),而不是用户提供的密码。我正在使用Windows身份验证。
PasswordDerivedKey
函数生成的密钥,通过传递密码和12字节的盐。我已经在应用程序代码中实现了逻辑,“密码”是登录用户的用户名,“盐”是静态字节数组。如果密码只是Windows用户名的加密版本,为什么需要存储密码呢?
每当您需要加密/解密时,您都知道用户的名称,因此可以动态生成密钥。
盐永远不应被视为安全资产。无需隐藏它。您应该始终假设攻击者知道盐。盐只是一种打败彩虹表和其他快速查找的机制。
我是否有所遗漏?
编辑后 问题在问题陈述中被错误陈述。问题不是要存储什么/如何存储。那个答案很简单。除了盐之外,永远不要存储任何加密数据。
当前的实现从已登录用户的用户名创建加密密钥。问题在于确定用户名相当容易,这是不安全的。要解决这个问题,需要:
a)接受实现对于愿意反编译应用程序的人来说是不安全的。
b)...不是一个好主意...哈希值可以根据组/角色而改变
c)为每个用户使用唯一的秘密密码。
c是唯一安全的实现,但在加密或解密时需要提示用户输入密码。
或者,您可以简单地接受保护较弱并提供最小的混淆。这取决于数据的价值和可能攻击者的能力。如果攻击者具有足够的特权来反射实际机器上的程序集,那么他们很可能也是管理员,这意味着无论您做什么,情况都非常糟糕。有一些工具可以连接到正在运行的进程并监视其内存,这意味着他们可以等待您解密数据并从内存中读取它。
保持密码安全的最佳方法是在运行时生成盐并将其与其他用户信息(如用户名和密码)一起保存在会话中:
对于密码,不建议使用对称加密(甚至非对称加密)。您需要对其进行哈希处理,这只是单向的。
我添加了这个作为第二个答案,因为它是一个不同的解决方案。今晚我想到了它,因为我正在使用这个类(试图逆向工程Kindle加密)。
你可能想要研究一下受保护的数据类。
http://msdn.microsoft.com/en-us/library/2c64xe0y(v=VS.90).aspx
这是一个允许您在Windows加密存储中存储数据的类。
通过使用Protect和Unprotect函数,您可以将数据传递到加密存储中并从其中提取数据。
如果您不想强制用户创建(和记住)加密密钥,则可以执行以下操作:
1)检查当前用户是否在存储中具有加密密钥。
1a)如果没有,则创建一个随机的加密密钥
2)使用密钥加密文件并存储
3)要解密,请从存储中检索密钥。
4)另一个用户可能能够访问该文件,但无法从存储中获取密钥的副本。
一些注意事项。只有存储密钥的Windows用户才能检索密钥。但是,这取决于环境,可以绕过此限制。如果用户没有Windows密码(或Windows密码较弱),任何可以访问计算机的人都可以作为用户运行,Windows将很乐意交出密钥。在域环境中,任何可以模拟用户并修改密码的人员(管理员)都可以访问他们的密钥。如果用户的Windows配置文件被破坏,则您的加密密钥的唯一副本也会被破坏。