This is an issue I've been thinking about and searching around the internet for some months now.
In the specific szenario I have an application on a network share that connects to a database in order to retrieve some information. The connection string for the database is static, including username and password for establishing a read-only connection to the database. Clearly, the connection string can't just be stored in plain text but has to remain the same for all users that start the app from different computers around the network.
And this is the nut I failed to crack in a satisfying way:
All tutorials I've found so far are using the build in .net-functions for protecting the connection string section of the app.config file (like RSAProtectedConfigurationProvider), which is great for user-scope encryption but can't be used for the described scenario as the rsa container is generated for a specific user/computer an thus only this one user/computer is able to read from the once encrypted config file - or am I missing a point here?
My final attempt was to write a somehow obfuscated method to generate a static string inside the application, encrypted my connection string with it and call it every time a database connection needs to be established. That does the job but isn't very hard to be hacked by simple decompiling the program, extract the encryption/decryption method apply it to the also extracted connection string.
I was wondering if there is some technique to protect sensitive data like connection strings inside the applications scope so it is only known by the app itself and static for all users BUT can't be extracted by simply decompiling the program.
Maybe I'm thinking completley inside the wrong box here, but I find it pretty obscure that it seems like there is no out-of-the-box-solution for this pretty commonly seeming problem.
This is the reason many architectures involve a server application as an intermediary between the client application. This way the encrypted config uses the context of the user that the server application runs under(for example with a web application the identity the ASP.NET App Pool runs under) so that client users have no access to the configuration nor to the database directly.
Intranet Apps connecting directly to database
Your scenario is pretty common for intranet desktop applications, and since your client application accesses the database directly, the best approach is to use per user permissions at the database level. This can be accomplished using Integrated Security connection string instead of using a SQL username/password. Within SQL server you would map a Active Directory group to permissions, and anyone who will use the application must have their AD user added to the AD group. Generally this is sufficient for small intranet environments, where users are somewhat trusted and accountable for their actions.
This ensures no one without authorization can grab a copy of the application and use the connection to perform unauthorized queries against the database. If you are really concerned about security, you should treat any permission at the database level as if the user could leverage that permission.
For example consider this: Your application needs delete permission for the Product table because it has code that deletes a single product whenever the product reaches some Inactive date. However, any user can use that connection to delete the entire contents of the table, regardless of what your client app is programmed to do(of course it would require smarts on their part to create a tool to do this, but that is usually a mute point when talking about security).
This is the reason for the client-server architecture, because once you involve the server and clients no longer connect directly to the database, then you can be confident that the interaction with the database adheres to some defined behavior. When your client connects directly to the database instead, anyone using the client could with enough effort find a way to use that connection and abuse the permissions.