CONTEXT:
I have a c# .net application made for a customer. The application has no network communication. In fact, the computer it runs on wont likely have any internet or network access.
In comes our customer with a very specific and non-negotiable request:
Request a administrative password before opening up certain screens and grant certain rights. This password must be within the application. The default password (i'll probably set it to 'password') must be changeable, so it can't be hard coded. And there ought to be some way to return to the default in case they forget the password.
It seems kind of superfluous to me just to stick a encrypted password in a file, in the application folder. Anybody who deletes the file would erase the password.
Is there some widely known strategy for this?
Again the password is local and not authenticated on any network.
Maybe hide it in the registry? If the registry key isn't there, then just remake it and set it to the default password. Hardcode the default password, maybe encrypted or something so someone who scans the .exe can't finde it. Also ask your client for what the default password should be, not simply make one.
The problem is, as long as you store something locally, everyone who really wants to know it, will find a way to get it. :/
If it is on windows (is it?)
Key Storage and Retrieval
MSDN Security Briefs Article (part 1)
MSDN Security Briefs Article (part 2)
Related
I'm working on portable application. Something you have on flash-drive and can use it anytime.
Problem is: I need to store some critical passwords in application.
So i would like to ask what is right approach for that?
Passwords need to be in xml settings file next to app or somewhere else, but settings still needs to load when used on different computer.
But i would like to users couldnt easily open that settings file(Can i cipher file with settings?) Then i would have some "decryption key" as password which you use everytime you wana make changes or want to use password from that file or some different setting.
Is this right or even safe?
I know option two would be save password already in cipher form to settings xml file, but i would like people couldnt open that file without knowing password.
Thanks for all answers or ideas.
1st way - encrypt your config with password.
1) Encrypt your whole XML config.
2) Request password on program start.
3) Decrypt config and load it.
Easy as that.
You can use RijndaelManaged to encrypt your settings with a string password.
Ready implementation of string cyphering can be found here.
Also I really-really recommend to hash your password with SHA256/SHA512 to make it harder to bruteforce it for someone else.
Pros:
You don't need internet access.
Breaking encryption like that will take a right amount of time (if you use it right)
Cons:
Anyone can bruteforce your password. So use a strong one.
2nd way - download your password from a web-server
Setup a web-server that will accept your password and send list of passwords.
ALWAYS USE HTTPS! All of your wifi connections can be sniffed/or MITM'ed!
Use SSL-pinning to reinforce your security! You can find more here.
Pros:
It makes really hard to bruteforce your password.
(Set up your serversided scripts to accept passwords only when you're working, for example)
Cons:
You need internet access, of course.
You need to host a website, get SSL certificate (for example here, for free)
People who have access to your webserver can steal your passwords.
People who have access to your device can install fake root SSL certificate to intercept your traffic. (SSL pinning can help you there!)
My solution to this problem following.
Encrypt the whole setting file ( you can create your own
encryption function) and create a small utility app to change the settings.
Only Encrypt the password and use a small utility to
update/create a password
Hi everybody i do not have a lot experience with c#. I want to write a very simple application, with must access a fileshare. The User (who executes the application) has NO access to that fileshare. So I need to use other credentials to access that fileshare. But I think it is not a good option to provide that credentials directly in the source code. I am thinking and thinking, but get no solution to that. Do you have a idea, how I could solve that problem? Is there a way to store the credentials somewhere, so that a possible attacker has problems to receive the used password?
You can't both give the user the password and prevent them from having the password. But every computing problem except for one, can be solved by adding an extra layer of indirection. Create something that doesn't run on the users machine, that acts as a middleman between the file share and the user. I would suggest using the WebDAV protocol.
Forgive me if this is a stupid and obvious question, but I'm having trouble googling for the correct resources. I'm not a security expert and I'm struggling to understand how to properly go about this.
Here's the scenario. I have an internal application on an internal server: not something that will ever go out to a client site. This application has a database of username and password pairs that are used to talk to secure web services. I have no need to keep these passwords secret from colleagues, but I want to protect them in case the server is attacked and the data stolen.
Traditionally one would salt and hash them. This is a process I understand in principle but it depends on the user entering a password which can then be validated against the stored hash. That's not the case for me.
So: searching around there are various solutions that use a fixed "pass phrase" to secure a string. Here's a one example, https://stackoverflow.com/a/10177020/271907 and here is another https://stackoverflow.com/a/10366194/188474.
However, as I understand it neither of these offers a useful solution in my case. That "pass phrase" is going to have to be stored somewhere for my application to do its work. If I hard-code it into the application it can be reverse engineered. If I encrypt it and put it in a separate file it can be stolen and worked out using a rainbow table.
I looked into using reg_iis to encrypt a key as per Encrypting Web Config using ASPNET_REGIIS but, to be honest, that just left me even more confused. I'm not even sure whether or not these encrypted config files can be ported between machines or whether I'd have to re-encrypt between dev and test and live. I don't know how secure they are either: AFAIK there has to be a key somewhere and if there's a key it can be broken.
To further muddy the waters I found this answer which doesn't use a key: https://stackoverflow.com/a/10176980/271907. However the author admits it's out of date and I have no idea how secure the result is.
Is there any kind of sensible approach to solving this problem that doesn't leave a hole in the security somewhere?
Any solution where you decrypt the password to check it is going to fundamentally be insecure because your application must always know how to do that decryption.
You can make it harder by not storing the decryption key in the code, but wherever you put it a hacker that can compromise your code can probably access anything it can access too.
Even if your application security is rock solid; your passwords are still plain text in your DB and if that gets compromised then lots of your users are exposed.
That said - this is an internal-only, low risk system. Your best course of action may be to let your bosses know the relative risk vs the cost of proper security and let them make an explicit business call (and carry any future blame).
The only way of doing this without leaving a hole in the security is by hashing and salting the passwords with a one-way algorithm. The fact that current passwords are plain text shouldn't be a problem - there are lots of ways to push users to encrypt them, but easiest is just to do it for them: next time they log in, if they have a plain text password encrypt it. Then after a suitable wait (depending how often your users log in) remove the old password and check against the new hash.
The golden rule is: if you store passwords you must hash them in a way you can't reverse
The only other option is for you to not authenticate at all - use NTLM or AD or OAuth to get some other service to authenticate the user and just trust that source instead.
If instead you're looking to secure the credentials the application uses itself then you have a similar problem, but the focus shifts. You still can't do much to avoid exposure if the host machine is compromised, but most attacks will only target files.
This can be a problem if all your connection details are held in a web.config or appsettings.json as compromising those files can expose your SQL server or other service passwords.
This is where you can use ASPNET_REGIIS - it lets you add secret configuration that IIS can access, but that isn't held in plain text with the web files.
In .NET core there's new Microsoft.Extensions.SecretManager.Tools that do the same thing.
Both of these add a layer of protection for any application credentials that would otherwise be stored in plain text on disk. Attackers must compromise the machine to get at them, rather than just the files.
In both cases these configuration details are no longer portable - you'll have to set them up again (and re-encrypt) on each server.
However, you only really need the additional protection in live - in development or testing sandboxes you can just use the plain text config, and then override the details with the encrypted settings on the live server.
I am extending an open-source VoIP softphone application (written in C#/.NET) to my needs but don't know how to best approach this issue. I want the application to connect to database when a user enters his email address to log in, and perform a SQL query to fetch his account number using that email and authenticate with account number. But, I think including my MySQL connection credentials (host, username, database) is insecure? How should I do it?
It is indeed insecure.
You need software running on the server, that can accept said email and password as input and connect to your database (so the connection string is sitting on a machine in your control), check it and return either ACCEPTED or DENIED to the client. In your case, ACCEPTED could be just the account number you mention.
Bonus points if the email and password are transmitted from client to server app over an encrypted link (public key).
You should put the connection strings into a configuration file and then encrypt that portion of the file. There's a tutorial on how to do that here: Protecting Connection Strings and Other Configuration Information. Although the tutorial is for ASP.NET, the same principle will apply to pretty much any .NET config file.
There's also a similar question here: Encrypting passwords in WinForms app.config, .NET.
Our rule of thumb when designing database applications is to always use delegation and isolation.
What isolation means is that we isolate database interaction from the end user application through the use of services (i.e. web services, wcf, .net remoting, etc). In this way, the database is never directly exposed to the user.
What delegation means is that the database access is always performed on behalf of the end user by a well-known, limited-access database user (generally the user that the service is running as). If at all possible, the database access should be performed by a user authenticated by the network rather than by storing user names and passwords in connection strings or other semi-secure locations.
Finally, one important note: you should always encrypt your end-user's login and password information before sending it over the wire. This is a little extra work, but well worth it from a security perspective.
Can MySQL do Windows based authentication (i.e. on a domain)? If so, you could use that. Otherwise you might want to have credentials to a service, or use encryption, but you would need to include the encryption key so anyone dedicated to discovering it would.
You could code your connection strings so that they end up in your assembly and use a code obfuscator to protect it from disassemblers
There are many ways to do it, including obfuscation and other ways making it difficult to use outside of the application, but not impossible to retrieve/use.
How should you do it? The best way (as far as I know) is to give the account the minimum credentials necessary so that if someone does have the username and password he/she cannot do anything malicious with it. Permissions can be set up in many ways for user-specific data, such as views so a user can only access the correct rows. Basically, if security is a top concern, assign permissions conservatively and if necessary give different users different credentials.
You should host a (php/jsp/asp) script at your server with which your application will talk. you should not store your credentials inside the app at any cost.
Tthere are so many ways to just take out the information. Especially .NET applications. it doesn't takes more that 30 mins :p
I have a username and a password for an smtp server. Currently they are hardcoded in my code:
string userName = "username";
string password = "password";
Currently, anyone who disassembles my dll could see these strings, correct?
I wish to store these securely in the registry, in case of future changes to the smtp server, and/or the credentials. I am not worried about the smtp server address string's security. I am only worried about the credentials' security.
How do I do this without hard-coding the credentials anywhere? I wish to see encrpyted strings in the registry.
I can encrpyt the password, then store the encryption in the registry, delete the password from the code, and use the decrypted password assuming that it is correct. However, wouldn't someone who disassembles my code still be able to decrypt the encrypted string stored in the registry?
What is the safest way?
At some point, no matter how many layers of security you have, the code will have to use the unencrypted password. That means that someone with enough access to your system to view and/or modify the registry probably has plenty of access to your code to get your password no matter what you do.
I know as developers we tend to work with paranoia = Paranoia.Maximum; a lot, but sometimes you have to back it down some.
That said, there are some things you can do. If the credentials need to be that secure, consider storing them, if possible, in a remote database. You can store them encrypted on a remote server so that anyone having access to your machine won't necessarilly have access to the DB Server.
If you really want to turn the paranoia up, and make security the user's responsibility at the same time, have them provide a "secure location" for a file that contains the data. You can then recommend that the location be something like a thumb-drive which would be removed physically from the computer when your program is not in use.
In any case, with security, you want to think in terms of layers. No one thing you do will be sufficient for really good security, but by layering several measures you can increase security to the point it should be sufficient for your needs.
The problem is not new. Operation system starting with Windows XP hat credential API which can be used in different scenarios. For example CredRead (see also http://www.pinvoke.net/default.aspx/advapi32/CredRead.html) and CredWrite can be used to save in encrypted form any general credential information. In the corresponding fields of CREDENTIAL structure you can define for exaple the level of persistence the saved credentials (logon session, all subsequent logon sessions on this same computer or to other logon sessions of this same user on this same computer and to logon sessions for this user on other computers).
If you want that your application only read the credential information you can use CredWrite in a separate configuration utility used by administrators or use the API as a part of setup of your application.