How should I store passwords locally for a multi-user application?
I want to create a multi-user application, but I don't know how to save and read encrypted passwords.
procedure SavePass(Password: WideString);
var
Pass: TIniFile;
begin
Pass := TIniFile.Create(ChangeFileExt(Application.ExeName, '.PASS'));
Pass.WriteString('Users', 'USERNAME', Password);
Pass.Free;
The passwords must be stored on the computer. This works but it's stupid to sa开发者_高级运维ve passwords using this. Hashing passwords would be also good.
If the connecting software accepts hashed passwords, it's not going to stop people who steal the hashed passwords from connecting. All it will do is hide what the real password is.
Furthermore, if the software that you're connecting to does not accept hashed passwords (database, website, ...), you're going to have to store your password in such a way that you can get it back to its original state. A hashed version is not going to help you there.
If you want to scramble your storage so that humans cannot read the file, you could use Windows.EncryptFile()
and Windows.DecryptFile()
. In newer Delphi's that's neatly wrapped into IoUtils.TFile.Encrypt()
and IoUtils.TFile.Decrypt
.
If you really want to stop others from reading the cleartext version of your password, you're going to have to use some encryption with a key. Where do you store that key then?That would defeat the whole purpose of storing a password in the first place. It's better to prevent access by other users by using user privileges to the file system for example, because anything you or your software can do, a "hacker" can do if he has the same privileges.
My suggestion is to not use passwords in your application at all, unless you really need to. The user experience of having yet another password to enter & remember is usually not needed.
What I do for my applications is default to using the domain and user name of the current user as the identification. The user has already logged on with a password, or more secure system if they want it. Only by logging on can they be that current user. My server then accepts that as their identification.
Variations on this include optionally passing the machine name too, so that the same user is treated differently on different computers (when they need to use more than once computer at once). And of course you can still allow a normal password if you want to.
You should store hashed passwords. For example you could use one of the SHA algorithms from the Delphi Cryptography Package. When you check passwords hash the password that the user supplies and compare against that saved in the file.
Have you considered using Windows security rather than attempting to roll your own?
As an aside, you are liable to encounter problems writing to your program directory if your program resides under the program files directory and UAC is in use.
There are hash and encryption routines in Lockbox. You should hash the password concatenated with a random 'salt' and store the salt and hash together. To make it harder for people to brute-force the hash - trying all likely passwords until the right one is found - you should iterate the hash. When the user subsequently enters their password to login take the salt from your store and hash it with their entered password, and iterate, and test the result against the hash you have stored. If they are the same they have given the correct password.
- As long as you can, don't store password, but hash them properly (use a salt, repeat hash n times, etc.) because rainbow table attacks are feasible and work well against poor chosen passwords and too simple hashing.
- If possible, take advantage of "integrated security". Use Windows authentication to avoid storing passwords.
- If you really need to store a master password or the like, use Windows APIs like CryptProtectData to protect them locally.
I think its best to keep user-specific settings in the Registry under HKEY_CURRENT_USER. That will keep their settings all together and separate from other users' settings.
You'll automatically read the correct user's settings when you read from this area of the Registry, and you should store your password there as well. Yes, do encrypt it as David recommends. The Registry is easy for anyone to read using RegEdit.
Here's an article on how you can write to and read from the registry.
精彩评论