I have a C# application that comes with an app.config file. The application is built on a build server and deployed to multiple users.
I'd like to encrypt the app.config, but I'm not sure about when to do so: If I do it straight after the build, won't the encryption depend on the build server credentials? How can the application decrypt on other machines? If I do the encryption on the users machine, won't this leave time when the app.config is unprotected?
Thanks
Edit:
I was considering using DPAPI. It uses the user's credentials to encrypt and decrypt. This is why I think I might have a problem delivering an encrypted file to the users.
I just read the addition to your post, and I don't think you actually need encryption at all...
You say that you intended to use a system that would encrypt/decrypt based on the user's credentials. That means two things:
You don't encrypt during build; you can't use this sort of system during build, for the reasons yoy noted.
You seem to be OK with the users having access to the data. In that case, you should not be using configuration at all, but you should be prompting them for login info (perhaps saving it securely afterward to reuse) or just using their Windows/domain logins.
Either way, you don't need to encrypt the file to protect it... you simply need to store the login info, or other config info, as user settings, rather than configuration, which is readable to all users.
Related
I'm trying to figure out the best way to encrypt a password that is in a configuration file. We are not allowed to hard code the passwords.
This a requirement that I have to meet.
I'm using DOTNET core and this needs to work on windows 10, windows server and OSX.
Does anyone have any good ways of meeting this requirement?
Thank you
First, read up on RSA Key Containers. You are going to have your operations group create one for each of your environments. They will export them and keep track of the exports for you. They'll also ACL them so that devs have access to them in lower environments, but only ops folks have access in higher environments. They also need to add an ACL so that the process identities on your servers have access.
Those Key Containers will be imported on to the servers, and on any client machines that will be doing any encryption work.
Then create a C# class that has the secret name, perhaps an encryption timestamp, and two strings, one for the clear text secret, and one for the encrypted version. Make everything JSON serializable. Mark the clear text member so that it doesn't serialize.
Create a small client app (say, with WinForms) that can read in a collection of secrets objects, decrypting any encrypted text using a key in the Key Container. The app will allow users to paste in a secret (perhaps one copied from KeePass). When the file is saved, the clear text/pasted in secret is encrypted and serialized out. The clear text version is thrown away.
At that point, you have a JSON text file that contains one or more encrypted secrets, but those secrets can only be decrypted by processes running with a token that has access to the RSA Key Container. So, you can put the file in source control and rely on your build/deploy to push the file(s) out to your servers.
Sorry for the lack of code, but I really can't copy/paste code I wrote for my employer. There should be enough here to get you started.
Ok, I'm asking a rather generic question to a specific problem. I have searched this in more ways than I can count, and nothing seems to work. Let me explain my need and then I'll mention a few of the best solutions I've found and why they don't work in my case.
I have an application that a user launches and uses to set up various configuration values that are saved into an app.config file. This is a WPF application. Specifically, some of this data are HIGHLY sensitive.
This data needs to encrypted and subsequently decrypted by a Windows Service that will be launched by the application once the configuration step is finished. The general solution given for this scenario is to use DPAPI, which has two modes for encryption: User and Local Machine.
If you use User-level encryption, your application will encrypt and decrypt data as much as it desires, as long as the current user that initially encrypts the data is doing the decryption. My problem is that when the service is started, it also restarts on reboots and will specifically be running under a different user account.
The next approach, using DPAPI, is to encrypt the data as the Local Machine. This means that when ANYONE logs into the machine can decrypt the sensitive data. This is a BIG no-no!
What I need is to have a way for a user to specify the data he wants to encrypt and then specify an account (in this case, what will be the service account) and use it for data encryption.
I can't find how to do this. This MSDN article alludes that can be done. (See section 'Web Farm Scenarios'.) The TL;DR on that article is that for ASP.Net applications, you can use the RsaProtectedConfigurationProvider to encrypt your data, and export the keys to be used with a specific web account. This is close to what I want, but in my case I need to create the data in a WPF application and store it to be used in a Windows Server Service.
How can this be done?
You can accomplish something similar to this using something as mundane as EFS, but unlike raw DPAPI, a recovery key might bypass the protection. In either case, a local admin could replace your program with his own and it would have full access to the decrypted data.
As for setting this up, the easiest way to do that would be to interactively log on with the service account and either create the protected data using System.Security.Cryptography.ProtectedData or create a file in a directory marked with the "encrypt" attribute.
Use the account name as the salt for your encryption, decyption should use the logged in account name as the salt to decrypt.
i have a suggestion , you can create User group add required users into that group. And encrypt and decrypt data only if user is part of that group using second method.
If I have a stored key file used to decrypt the encrypted input coming into my application, and I store that key file as an embedded resource so that it is embedded in the assembly when deploying, how difficult would it be for someone to reverse engineer the application and retrieve the key file?
Also, the application is deployed through ClickOnce "Online only" mode which I imagine would also make it more difficult to reverse engineer? (I'm not exactly sure of the workings of ClickOnce but I wasn't able to find the dll's/assemblies on my local machine after running the application in online only mode...).
Update:
As Ralf essentially answered the main question below in his comment (answer: it's not really safe at all), here's some more information so that you knowledgeable people can possibly suggest a better security model.
The encryption will be used to encrypt the login password for my application, to be used in a SSO setup (the user will first sign on to a different system and then by clicking a link will be able to directly open my application without having to enter in their login details).
The encrypted data will be sent as a base-64 string URL parameter in the link that will launch the my click-once application.
I will also be developing the application that will create the encrypted data for the URL parameter (clarification: not the first application the user will sign in to for the SSO, I will only be creating a small tool to convert the plain text password into an encrypted base64 string).
It's only an internal application so bullet proof security isn't essential and ease of deployment is more important, but it'd be nice to know what the best practices and different options that are available.
Whether in clear text or encrypted, you don't want to store the password. When you get a password, all you should do is pass it to your server app where you compare it against the salted hash of the password you have in the DB. Even if you don't think security is that important, you need to take care with the password because people frequently reuse passwords across different systems. I know they shouldn't but they do.
If you want to implement a single sign on (SSO), create a sign on token on the server side and pass it back to the client, either encrypted or signed (HMAC is a good choice for signing). This is an unforgeable token because you need to know the encryption key or shared secret for the HMAC and that data is only known on your servers. So you have your SSO and all data involving the SSO is managed on servers so there's no data leakage or chance of spoofing.
As long as the aplication can be launched, the files have to be somewhere on the computer. You just have to know where to look. The reverse-engineering may be ugly but it is always possible. The computer has to be able to understand what he is supposed to do so you only have to extraxt the information one is looking for. Therefore the security of your application should never depend on the difficulty of reverse-engineering! I believe that a secure application should be open-source anyways.
You propably need a diffent security model. The important thing here is that you know against what you want to protect the data. If you simply want that you know the data is sent by the server and not somebody else (man in the middle attack) you could use digital signatures instead.
If you do not want anybody to read any data sent between server and client you should use some sort of ssl implementation to create an encrypted channel. Then you only need to watch out that the public key of the server is not altered on the client. This may be done by an certificate of an official CA but unfortunately those are usualy not for free.
I understand that i'm never going to be completely safe ... but paypal documentation seems to stress that I should never plain-text store the API credentials in my code (ie, web.config or in some C#).
1) What is a reasonable way to protect it... without going OVERBOARD?
2) If I encrypt the keys in my web.config... where do I store the encryption key... in the database, right? But then... the connection strings to my database are also visible in the web.config... so I don't understand why this is considered safety...
My website is an ecommerce store and will probably be on Arvixe business shared server.
I would encrypt the Paypal credentials and store this encrypted information in the web.config. Do the decryption in a separate DLL and obfuscate this DLL. You could also protect this DLL with an external protection system but we have had issues in the past where protected libraries don't always work correctly in shared web environments.
Is there any way, using C#, to monitor a specific file then change its contents before it is read by specific applications?
Here is the situation:
I have a Windows 2003 Server running ASP.NET with a configuration file (xml) which contains LDAP information. I want to have the LDAP password encrypted. I'm trying to devise a way to monitor that file, and whenever it is read, decrypt the LDAP password and pass that to whatever is reading it. Is there any way to tell which program is doing the read? I aldready have the encrypt/decrypt working but it is built into the ASP.NET installation; I would like to make it external. The encrypt/decrypt is RSA using key's from the key store.
If you want the encrypt/decrypt external to your main application, what about creating a separate .dll or webservice that does that. Then your call in your ASP.NET application is to your webserice or .dll.
Something like (Warining: Not Compiled- you'll need to clean this up)
WebServiceInstance instance = new WebServiceInstance();
string password = instance.PerformGetPassword();
Then, your ASP.NET service is unaware of the encrypted password at all. Additionally, if you have other applications which need to access the same file, they can call the same webservice.
I think this would be much better accomplished by using NTFS permissions on the file. Grant access only to certain users/groups, and ensure that any process requiring access to the secured data is running under the security context of a user that has the correct ACL permissions.