Storing a saved password in Open Source application - c#

I'm writing a C# application that will be open source and I need to be able to store saved login information for each user. Normally I would just encrypt the password and then store it in a user settings file, but I worry that because of the code being open source it kind of defeats the point of encrypting it. Since all anyone would have to do is look at the code and grab the encryption key.
Granted, it would at least make it a lot harder than the password being stored in plain text. But is there any decent way of encrypting the password, but making it still at least extremely difficult to decrypt it even if you had the source? Maybe make it so it would at least be nearly
impossible to decrypt on any computer other than the one it was encrypted on?
EDIT: Clarification... I'm storing CLIENT side passwords, NOT passwords to validate their login for the service. It's a client to a pre-existing web service of which I have no control. I just want to store the passwords locally for automatic login... like any chat client would.
EDIT 2: Totally sorry for not being clear before. But passwords have to be retrieved in clear text at some point and hashing is NOT an option :( Even if the service would let me pass the password hash that would kinda defeat the purpose because the hash would be as good as a password :P

What you are asking is basically, impossible.
There is no way to safely store a password on a client machine if it needs to be decrypted. This is further aggravated by the fact that you need it to connect to a service, which I presume does not support SSL. In this case, one could trivially find the password by using a network analyzer.
There is a game (closed source, of course) I play that requires a login, the password is saved somewhere but it's encrypted with a key that's unique to each install. I forgot the password once, so I just used Wireshark, and voila - I could see the plain password.
This also reminds me of people complaining about it being easy to reveal passwords in Google Chrome... They obviously don't know better. You can try all the clever tricks you want, but any application security is thrown out the window once someone has access to the machine.
So with this in mind, I would keep the encryption and decryption really simple. At best, you can create a key derived from something unique to the machine, so someone who steals the encrypted password will be unable to decrypt it without access to said unique key.

If you are using this application in Windows you can use DPAPI for storing sensitive data on behalf of the user:
How To: Use DPAPI to Encrypt and Decrypt Data (C#/VB.NET)
Also storing the hash only instead of the full password is a good idea!

I think if you use Rijndal for instance and create random salt values and derive the keys from machine specific things (like some hardware IDs) it will be hard to decrypt, even if you know how it works because you are missing the information of the hardware.
But you might consider storing hashes of the passwords only and iterate at least 1000 times. Hashes cannot be covnerted back to the original password.
Yet another idea: would it maybe be an option to just leave the implementation up to who ever is going use your source and make the encryption abstract? Doesn't work of course if you offer a built bundle to download. But then again: in the build you could use your own "secret" encryption and stull have it abstract in the source.

Maybe you can encrypt password using some machine specific values, like mac or sth.. If someone get source and encrypted password but no full access to the machine password should be safe.

Yuo could use babushka doll encryption. You encryt the password with another password, then encrypt that with another password, and do that lots of times eventually writing the last password in clear text. Anyone who wants to get access to the orignal password will get sick of all the unencrypting and give up before they get to the original password.

Related

Store password in portable application

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

Best practice for storing passwords that need to be reused?

We have an automation platform that needs to store service account passwords in a database.
These passwords are used in a variety of different cases but generally need to be reversed into their original plain text form in order to be functional.
The service accounts are all compartmentalized to do very specific things - however, I'm uncomfortable leaving them in the database in plain text.
What is the best method/technique for storing passwords in a database when they need to be reversible?
For specific recommendations the platform is using C#, .Net MVC, and MySQL (MariaDB).
My immediate plan would be to store them after signing them with a non-exportable private key held in the local key store on the application server. Then reversing the encryption method when reading them out of the database.
If this is the technique I should be using are there particular methods I should be aware of?
Thank you for any help or information.
[Edited To Re-Open and remove the "Opinion Based" classification. Microsoft had particular documentation for this exact use case. I can't add an answer or mark as answered until it is but my solution is as follows:]
The recommendation from the Microsoft Engineering team was to use the Machine Key class and methods.
Utilizing a machine key set and generated via IIS and a uniquely generated "purposes" string provided to the Protect method I can securely encrypt and decrypt a column and leave it secure while at rest.
In MariaDB (MySQL) you'll need to use a column of tinyblob to store the byte array.
I don't believe this is an opinion based answer since this is the defacto way to do it with the technologies specified in the question.
Usually, to perform activities on behalf of a user with another service provider, you would use a scheme like OAuth2.
In this case, I assume this is not available or provided.
The issue with encrypting passwords as compared to hashing them is that encryption is a two-way function, it can be reversed, and this is in itself a security issue, since anyone with the key can decrypt the password. The issue then becomes how do I keep the key safe?
The answer is simple: Don't keep the key anywhere on your system.
Use your own users password to derive an encryption key, and then use this to encrypt their other passwords that you are storing for use with other services. When you need these passwords, the user must provide their "master" password to authorize the action
This has the benefit that if your database was compromised, no passwords would be recoverable. Additionally, if your front facing server was compromised, the only attack vector would be to modify the behaviour and wait for users to attempt to login.
From a more technical point of view, do the following:
When a user creates an account with you, derive a key from their password (PBKDF2 is a good choice). Let's call this k1.
Randomly generate another symmetric key, let's call this k2.
Encrypt all external passwords for other services with k2, which you can get each time by deriving k1 again and then decrypting.
If the user wants to change their account password, simply decrypt k2 with the old k1, derive a new key from their new password, and encrypt k2 again with the new key.
You should really avoid storing user passwords in a form that is reversible. But if you absolutely have to, the above is a good approach that keeps things relatively secure.

How to encrypt and decrypt sensitive information in C# without a user-entered password

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.

Securing a password in source code?

I have a password in my code which is needed to connect to a sftp server. Whats the best way to "obfuscate" or hide it in the code?
Thanks
Don't store you password in your source code, store it in a protected section within you App.Config (or Web.Config).
See Encrypting Configuration File Sections Using Protected Configuration section in this Microsoft Doc
This works by encrypting the encryption keys using built-in Windows stuff, locked to the MAC address and various other undocumented things.
This will even work if you are using more than one server:
... if you are planning to use the same encrypted configuration file on multiple servers, such as a Web farm, only the RsaProtectedConfigurationProvider enables you to export the encryption keys used to encrypt the data and import them on another server.
Using this, if someone wanted to get your password, they would have to first break the Windows security on your server (not impossible, but harder than looking into your IL for the password by far).
I actually consider using the "protected sections" feature in App.Config or Web.Config to be LESS secure than storing the password in your code.
Anyone with server access can decrypt that section of the config just as quick as you encrypted it by running the decrypt command described in the article everyone keeps quoting:
aspnet_regiis -pd "connectionStrings" -app "/SampleApplication"
https://msdn.microsoft.com/en-us/library/zhhddkxy.aspx#Anchor_1
So this feature of ASP.Net only adds security in the case that a hacker somehow had access to your web.config but not your entire server (happened in 2010 as #djteller mentioned in the oracle padding attack comment). But if they do have server access, you're exposed in one cmd call. They don't even have to install ildasm.exe.
However, storing actual passwords in your code is a maintenance nightmare. So one thing I've seen done is storing an encrypted password in your web.config and storing the encryption key in your code. This accomplishes the goal of hiding passwords from casual browsing while still being maintainable.
In this case a hacker has to at least decompile your code, find your key, and then figure out what encryption algorithm you're using. Not impossible, but certainly harder than running "aspnet_regiis -pd...".
Meanwhile I am also looking for better answers to this six year old question...
Don't bother.
Anything you can do, your attacker can trivially undo.
If it only needs to run on a single machine, however, you can use the ProtectedData class, which will protect it securely against anyone not on that machine and/or user.
In general, the only remotely secure way to do this is to store the key in a separate, secure, location.
For example, you can encrypt it using a (non-MD5) hash of a password, then require the user to enter the password so that you can get the hash. (The hash and password themselves would not be stored anywhere; you should make a separate hash to verify the password)
Best way is don't!
Failing that:
Encrypting Configuration File Sections Using Protected Configuration
There are no "best way" to store password in source code since it can be recovered in many ways.
You can obfuscate password string or even encrypt it to prevent reveal thru simple viewing but it can't be treated as serious protection.
You can put it as an encrypted value in the web.config file. It doesn't look too hard:
K scott Allen tutorial http://odetocode.com/blogs/scott/archive/2006/01/08/encrypting-custom-configuration-sections.aspx
I think there's a Scott gu blog post with links to other information.
http://weblogs.asp.net/scottgu/archive/2006/01/09/434893.aspx
Encrypt it with something strong like AES, but as implied by SLaks, your attacker can reverse engineer your code and work out the encryption method and key. All you are doing is adding a layer which keeps script kiddies and a certain level of attacker out. Someone who really wants to work it out, can do. They could also run your program and watch what password is sent.
Don't save your password in the source code.
Read this:
http://en.wikipedia.org/wiki/Security_through_obscurity
There is no good way.
All you can do is use a smart algorithm to encrypt the password.
An experienced reverse engineer would manage to crack it.
There's not much you can do against someone who really wants your password. However, if this isn't a public app (intranet? in-house app or something) you could simply encrypt it using a symmetric encryption algorithm, or do something like base 64 encoding it.
You could also run an obfuscator over your code to make it less obvious that there is a password in there somewhere.
Do you have another option? Raw SFTP access is kinda dangerous, maybe you can create some sort of proxy service in between, which only allows the specific actions your app requires. Storing the password for that service in your code is a not as risky as storing your SFTP password in your code.
You could use something like SLP Code Protector to block reverse engineering of your assemblies. Still, I agree with everyone else, it's not the best idea.

Encryption to protect files from changes

I've been reading a little about encryption recently and am interested in protecting a licence file from tampering. Now this may not be the best way to do it, in which case I'm open to suggestions. But one way I was thinking of protecting it is to simply encrypt it.
However if I were to use encryption I'd need to use symmetric key, but this raises the question. If I store a key in the source code, with such tools as reflector, is it really worth it? It seems a fairly trivial task to obtain the initalization vector, salt, key etc and therefore break the encryption. Is there a way to protect a key in source? Or is this the completely wrong approach?
If you want to prevent tampering, you want signing/hashing, not encryption. Similar theory - but it means you can validate the file with the public key in the app, without requiring the private key that you keep on your server (and use to issue licenses).
Search for cryptographic hashing / signing.
Anything on the client side of the system can be compromised.
If you encrypt your file you must also somehow place the decryption key in your program. Anyone with a hex editor will be able to step through your code to find this key and then decrypt your license file and also create keys for your system.
Internet activation would be a good way to go, but I would see if you can find third parties to do this for you as they will have been down these roads before.
That said running your license file through some AES 256 encryption can't hurt :).
if you are speaking about MS/.NET environment, i recommend you the DPAPI.
It is an API used to store your data protected by a password. Then you can ask me "but then i have the same problem", the answer is no, because in this scenario you use a user password to protect your data. So what you have to do, to access your data, is run your application under a certain credentials. In MS environment, its the the best solution.
from the documentation:
DPAPI is focused on providing data protection for users. Since it requires a password to provide protection, the logical step is for DPAPI to use a user's logon password, which it does, in a way. DPAPI actually uses the user's logon credential. In a typical system, in which the user logs on with a password, the logon credential is simply a hash of the user's password. In a system in which the user logs on with a smart card, however, the credential would be different. To keep matters simple, we'll use the terms user password, logon password, or just password to refer to this credential.
What you're attempting is DRM; there is no 100% way to do this on current PC hardware. There are many measures you can take to obfuscate parts of your program. It's a tradeoff between how much you want to obfuscate and how many hurdles you want to make your paying customers go through.

Categories

Resources