我想创建一个多用户应用程序,但我不知道如何保存和读取加密的密码。
procedure SavePass(Password: WideString);
var
Pass: TIniFile;
begin
Pass := TIniFile.Create(ChangeFileExt(Application.ExeName, '.PASS'));
Pass.WriteString('Users', 'USERNAME', Password);
Pass.Free;
密码必须存储在计算机上。这有效,但使用它保存密码是愚蠢的。哈希密码也很好。
如果连接软件接受散列密码,它不会阻止窃取散列密码的人连接。它所做的只是隐藏真正的密码是什么。
此外,如果您要连接的软件不接受散列密码(数据库,网站等),则必须以使其恢复到原始状态的方式存储密码。散列版本不会在那里帮助你。
如果您想打乱存储,以便人类无法读取文件,您可以使用 Windows.EncryptFile()
和 Windows.DecryptFile()
.在较新的德尔福,它被整齐地包裹成IoUtils.TFile.Encrypt()
和IoUtils.TFile.Decrypt
。
如果您真的想阻止其他人读取您的密码的明文版本,则必须使用密钥进行一些加密。那你把那把钥匙存储在哪里呢?这将首先破坏存储密码的全部目的。例如,最好通过使用用户权限来防止其他用户访问文件系统,因为您或您的软件可以执行的任何操作,如果"黑客"具有相同的权限,他都可以执行。
我的建议是,除非你真的需要,否则不要在你的应用程序中使用密码。通常不需要输入和记住另一个密码的用户体验。
我为应用程序执行的操作默认使用当前用户的域和用户名作为标识。用户已经使用密码登录,或者使用更安全的系统(如果他们需要)登录。只有登录,他们才能成为当前用户。然后,我的服务器接受它作为他们的标识。
这方面的变体还包括选择性地传递计算机名称,以便同一用户在不同的计算机上得到不同的对待(当他们需要同时使用多台计算机时)。当然,如果您愿意,您仍然可以允许使用普通密码。
您应该存储散列密码。例如,您可以使用 Delphi 加密包中的 SHA 算法之一。检查密码时,对用户提供的密码进行哈希处理,并与文件中保存的密码进行比较。
您是否考虑过使用 Windows 安全性,而不是尝试自己的安全性?
顺便说一句,如果您的程序驻留在程序文件目录下并且正在使用 UAC,则很容易遇到写入程序目录的问题。
密码箱中有哈希和加密例程。您应该对与随机"盐"连接的密码进行哈希处理,并将盐和哈希存储在一起。为了使人们更难暴力破解哈希 - 尝试所有可能的密码,直到找到正确的密码 - 您应该迭代哈希。当用户随后输入密码登录时,从您的商店中取出盐并使用他们输入的密码进行哈希处理,然后迭代,并根据您存储的哈希值测试结果。如果它们相同,则它们提供了正确的密码。
- 只要可以,不要存储密码,但要正确散列它们(使用盐,重复散列n次等),因为彩虹表攻击是可行的,并且对选择的密码不好和过于简单的散列效果很好。
- 如果可能,请利用"集成安全性"。使用 Windows 身份验证以避免存储密码。
- 如果您确实需要存储主密码或类似密码,请使用Windows API如CryptProtectData在本地保护它们。
我认为最好将注册表中的用户特定设置保留在HKEY_CURRENT_USER下。这将使他们的设置保持在一起,并与其他用户的设置分开。
当您从注册表的此区域读取时,您将自动读取正确的用户设置,并且您也应该将密码存储在那里。是的,按照大卫的建议加密它。注册表对于任何使用RegEdit都可以轻松阅读。
下面是一篇有关如何写入注册表和从注册表读取的文章。