What is the best method for saving passwords on a computer so that they can not be accessed? I would like to store them in the Registry encrypted. I would like you to be able to reset the password but this is not for the server. This is for storing them on a computer to remember them and sign in automatically.
IMPORTANT EDIT: I need to be able to retrieve the plain-text password from within the program, just not anywhere else.
CryptProtectData and CryptUnprotectData are your best bet on Windows. They encrypt the data using login credentials, so the passwords are safe from attacks to the disk. However, they can be accessed by any program running under the same user. I would recommend storing them in a file whose permissions prevent other programs from accessing them (such as a file that requires administrator privileges to access).
The managed class ProtectedData uses these function, so it can be used from C#.
You can also use these functions directly using P/Invoke. There is some example code that does exactly that here.
Expansion in response to additional requirements:
There is a way to ensure that your program is the only one able to access the password without needing your program to be launched with administrator privileges, though it will take a lot more work.
The basic idea is this: you create a Windows service that is installed when you install your application. It should be launched on demand from your application when it wants to store/retrieve the user's password. The service will simply provide read/write access to a file with permissions set so that only administrators can read/write it. The additional security comes from the IPC connection to the process, which will use a Named Pipe. You can then use GetNamedPipeClientProcessId (sorry, you need P/Invoke) to authenticate the request by looking up the process ID of the client that connected to the pipe.
Depending on how worried you are about security, you can verify the process ID using code signing, if you have access to a valid certificate. Or, you can verify the checksum of the executable or something of that nature.
This is the only way I can think of to create the security you are looking for on Windows. Your application should also use ProtectedData to encrypt the data before handing it over to the Windows service to protect against hard disk attacks.
I believe what I'm looking for is AES. This seems like an easy way to store a password. Of course, this is only for remembering a password on the computer so the user does not have to type it.
http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
Related
I'm trying to figure out the best way to sign data (log-data, etcetera) written to file by a C# desktop application. Somehow the application, and the application only, needs a private key (secret) to encrypt the checksum/hash of the data.
The reason: Only the vendor should be able to tell if data produced by the application has been tampered. Only the integrity of the data is importent. Confidentiality is not a problem (encryption not needed).
The vendor has no control of the on-site installation process (read: can't enter secret manually during the installation process).
The customers doesn't nessecarily have a Internet connection or other means to retrieve the secret from a secure communication line.
Users (customers) may or may not have admininstrator-privileges on the computer where the application is executing.
The vendor will NOT hardcode (and obfuscate) the secret inside the application (or its installer).
Installing a certificate containing a private key along with the application seems to be a dumb idea, but maybe its not?
Is it possible to sign the application with a certificate and extract the secret/private key from the certificate somehow? (implementing a mechanism to create a private key is NOT a good idea, though. The secret must be associated with the key only according to good security principles).
Does anyone have any experience with the best way to solve this challange?
I have only been programming for the better part of 1-2 years, C# the last 7 months or so, Up til now I have used the .config file to store needed settings that cannot be stored in the database, and it was okay to do so.
Now I have a client where there are many users that will access a database, and part of the spec is that the application must log into sql using the sa username, obviously if anyone gets hold these settings it would be a problem.
I want to know what the best practice for something like this would be, I can encrypt the password and server address, but I still feel uneasy about this.
What is the best practice in the industry for storing settings that cannot be in the database, especially the ones that are sensitive configurations
Many Thanks in advance
You can put settings into a local database. I prefer MS SQL Server Compact 3.5, which is free. This way you can store your settings into a local SDF database file, which can be encrypted and password protected. The data stored in the SDF file can be accessed using e.g. ADO.NET+SQL, but I prefer Linq-to-SQL.
EDIT:
Please take into account that although SDF files can be encrypted and password protected, if the file is stolen, it can definitely be cracked by a brute force method. The same is true for any other solution, which stores sensitive data on client machines.
You can try to store information in Isolated Storage
I can't recommend highly enough to revisit the requirement to have the sa account used by the application. That is a HUGE security hole. Given the information provided, I would recommend encrypting the connection (won't really matter where you store it). Make sure that if your database connection methods fail, the error result won't display the user name and password.
The best practice method (I think) would be to use SQL server integrated security: (you authorize a Windows/Active Directory user to access the server, the security aspect is now handled by Windows and your Domain configuration) - however this is not always practical, and you might not want to give the windows user that much access to the database outside the client software (eg, the application must insert/update/delete records in the database, something you wouldn't necessarily want the user to be able to do if they logged into the DB via SSMS)
Another method would be to use the 'Protect' and 'Unprotect' methods of the System.Security.Cryptography.ProtectedData class to encrypt and decrypt the password, and/or the connection string. (you will need to set a reference to System.Security.dll).
This gets around the "where do you hide the key" issue - the ProtectedData class uses your Windows machine's entropy pool to generate a key. You can add your own salt (by way of a byte-array as "additional entropy") to ensure that the data cannot be retrieved by another .NET program running under the same user-context also using the ProtectedData class. You can 'protect' the password/data so it can only be 'un-protected' by the same user on the same machine that protected it.
Hope this helps :)
Cheers,
Simon.
I need to create a file that will be used to store confidential data; the goal is to end up with an ACL that restricts access to the domain\user running at the time of the create. But the default seems to also allow unrestricted access for SYSTEM and for Administrator.
Two questions: first, is there anything in Windows or .NET that breaks horribly if SYSTEM and Administrator are denied access to a file?
Second, from C# how do I actually obtain the desired permissions? I'm just doing a File.Create("myFile.dat") right now; clearly that version of the API isn't the one I should use. I found a very elaborate alternative, but it seems to assume that I know the current domain name and user name; is that actually the only way to do it?
Thanks!
As far as I know this is not possible.
Unless I am mistaking SYSTEM has access to everything, period. I'm pretty sure that is the point. Administrators are similar in capacity, they can't be very good administrators if they can't even access files that those with less permissions can (exceptions exist of course). But if SYSTEM was unable to access the file, how would any operations be accomplished on it?
Thinking about it logically, I would have to say "no, it is not possible." Though it is possible also, that I am incorrect.
As far as I know, Administrator can access anything, regardless of the protection you set on it. You could encrypt the file, and hard code the key in your app.
look at the forth overload for System.Io.File.Create. The fourth argument is an System.Security.AccessControl.FileSecurity object. That should do the trick.
I suggest you check out Encrypted File System. It's built into XP Pro, Vista, and Windows 7. (As well as the server products.)
It allows you to do exactly what you're trying to do. Only the user you encrypt the file with (i.e., the credentials associated with your running application) will ever be able to access the file in question. Not even local admins can read the file, regardless of the file system permissions.
You can use System.IO.File.Encrypt / Decrypt to perform the operation. The best part is, the user can still just double click the file to open it. No password. No custom application needed.
Be aware the somebody with a recovery certificate (typically a domain admin) can still decrypt the file, but there is nothing you'll be able to do about that unless you create your own encryption mechanism and prompt the user for a password everytime the try and open it.
Why don't you use the symmetric encryption technique and save the key for every user in database or registry ?
I am aware of the many cryptography providers that are available in the .NET framework along with the basics of how to use them. This is simple enough.
But my concern is this.
Lets say I want to use these libraries to encrypt XML serialized objects to prevent tampering and the ability of anyone to come along and view the contents of these files.
The problem that I am always left with is that the key to decrypt this data would need to be stored as a constant somewhere in my application. Essentially rendering the entire exercise pointless.
So, how does one store a key for an encryption algorithm securely inside of a disassemblable application?
EDIT: So If I am understanding both answers below correctly. What this means is that essentially any implementation (to be secure) requires it to be readonly or writeonly but never both? Is this correct?
You don't. If the application can access the key, it is just security by obscurity. It is better to authenticate the user in some way (a password is the simplest example), to make sure he is allowed to access the data. You can't let the application do that for you, because it simply isn't trustworthy. Anyone can obtain the information stored in the application.
If the key information is stored somewhere else, a malicious user or application can probably access it, too. If not, then store your data directly to that magical safe place.
Now if you still want to go down that path and store sensitive data without authentication, your best bet - or at least an easy way that is halfway secure - is probably the DPAPI (see the ProtectedData class in System.Security.Cryptography). It will encrypt the data either with the machine key or to the user account key (you can select that). So that a program running on another machine or with another user account can't access it. Windows will try to protect those keys but in effect any application running on the proper machine or with the proper user account may be able to access your data.
We'll assume you're using some kind of public key cryptography scheme, because otherwise it would be pointless.
The answer is you do not store the private key anywhere in the application. You store it somewhere where only your application can get to it. For example, a file in the local system that only admins and your app have rights to read it. On a protected network share. Etc.
Think about how we manage keys as people. We keep our private ones in a file maybe, or an encrypted USB drive or something like that. The same principles apply to applications.
There a various possible solutions. One of them is using RSA. Alternatively you could use the same approach used in TLS.
One good way would be to generate a pair of public and private key. Encrypt with the private and destroy the key. With the public key, you could decrypt but not tamper the data.
Collecting given answers: All encryption security relies on protection of a "root" password. This cannot be guaranteed in a compromitable system.
A feasible hardware architecture is given by e.g. Chip Card Readers. As external systems they cannot be compromised by internal malicious manipulations.
Accordingly you could set up a separate "Secure Server" with strongly restricted access, e.g. key board and local network. This server would provide sensitive data like passwords by secured communication with authenticated clients in a limited time window.
Suggested measures for clients in this time window are clamping spyware, messengers, remote control server and basically internet access, process monitoring, ...
... or you do all sensitive data processing on secure platforms, excluding talkative ones like Windows.
In a CodingHorror blog post a commenter made the observation that it is more difficult to obscure sensitive configuration information (e.g. SQL Server connection strings) in a program than it used to be, because the obscuring algorithm can be disassembled quite easily with Reflector.
Another commenter suggested that encrypted appSettings could be used as an alternative.
How secure is encrypted appSettings? Is it a bank vault, a locked door, or an open window, and why? Is it ever safe to store "sensitive information" in an executable?
Encryption algoriths are secure: the main issue with using encryption for security is the secure management of keys.
Hiding keys in the application executable was never secure, but it's probably true to say that they would be easier to find in a managed executable using a tool like Reflector than in a traditional unmanaged executable.
Encrypting a configuration file can be useful on a server. For example, if you encrypt web.config using DPAPI with the machine key, only users who can log in to the server or have write access to the server disk will be able to decrypt it:
Anyone with read access to the server disk over the network, or access to a backup copy of the application directory won't be able to decrypt it.
The real question is who are you trying to shield the user and password from? On a desktop app the user is likely to have access to the database with his/her own account, no pwd needed (trusted). On a web app, the config file sits on a (hopefully) protected place. So far I didn't find many reasons to encrypt the config file.