Save encryption key in WPF Application - c#

We are creating an application with WPF that will be used by our clients to do calculations.
We need certain data in order to be able to do the calculations. This data should not be accessible by the clients. This data can be stored in an XML file.
We also want to be able to control who uses the application. We planed to do this via a license file that specifies how Long the application may be used.
We wanted to encrypt the file with the data and with the license file so that the users cannot open them.
My problem is that I need to store the encryption key somewhere.
When I hard code this key into the application it can be discovered via decompilation.
Is it possible to save the encryption somewhere without the user being able to access this? Where could I save this key?
Do some libraries exist to achive this?

Check Rihino licencing project.

If all data is on the client and nothing is validated from a server, there is always a way to hack your client application. You should instead make a service that does the calculations and the wpf application is just a thin client that access the server and within each request the client license is provided and validated if the client still has access to the service.

You can use obfuscation to protect your code from being reverse engineered. Check this link from MSDN.

You can still store the key on a distant server / on a website.
Or you can move your whole method server-side using Litecode, here is an open source project written by 'debug-hf' which will help you figuring out how to do so.

Related

How can a user encrypt a configuration file to be used by a service application?

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.

Store key file as embedded resource (how unsafe is it?)

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.

Protecting Facebook API Secret in C#

Given that C# can be decompiled incredibly easily, exposing all set variables as well as functionality, is there a way I can fully protect the API Secret that Facebook provides for creating an App?
Thanks
A general rule of software design is to not trust the client. Whatever the client can do, anyone can do. You can try some security by obscurity and have a method that does something to "generate" the secret or you can hide it away in a seemingly unrelated class, but at the end of the day, anyone with a little bit of time can just look at the outgoing packets and extract the key from that.
If you want real security, route all your networking through your server. Have the client send commands to your server, which will interpret the commands and use the Facebook API with your secret to send the client back the proper data.
One possible solution to this problem is to store these credentials in your app.config file and then encrypting the section containing these credentials using DPAPI.
http://msdn.microsoft.com/en-us/library/ff647398.aspx
Decrypting config values is transparent and can still be done through the ConfigurationManager class.

Securely storing (encrypting) data in an ASP.Net application

I have an asp.net application, accessed by people over the internet using web browsers. It runs on a web server and it talks to a backend database.
Some of the users would like to use the application to store some private data. The requirements of this are:
1) Only the user who stored the data should be able to see it.
2) The developers/dbas should not be able to see the data.
3) If the web server and database server were compromised a hacker must not be able to decrypt the data.
So, it's obvious I'm going to have to encrypt this data. If I encrypt it there will be a key somewhere and probably a salt/IV. The question is where do I store the data which is used to perform the decryption? If I store it in the database or the web server then a developer, dba or hacker can access it and decrypt the data.
I think my ideal solution to this would be for the private key to be on the clients machine, that way they are entirely responsible for it. But I'm not sure of how to go about this with an asp.net web application.
I believe I can create a certificate which also stores a private key (PFX). The client companies could use group policy to deploy the certificate to their domain. But it is possible that the ASP.Net application can request the web browser to send the private key to it so that it can perform the decryption? Decrypting on the client would be best but other than creating something in javascript I don't see how this is possible.
Any advice welcome.
Store the key in the mind of the user. Use any password/passphrase based key derivation algorithm you like. The standard is PBKDF2. The optimum choice of algorithm will depend on precisely what your security requirements and threat mode is. Ideally, that decision and the implementation should at least be reviewed by a security expert.
Is it possible that you deploy a ClickOnce application as a part of your solution? The ClickOnce could easily access the cert store on a local machine thus allowing you to perform client-side encryption.

Monitor File for Read and Change Data?

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.

Categories