Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to protect sensitive data in the code?

I was examining the ways of protecting my code from decompiling.

There are several good threads here describing obfuscation and code packing as the possible ways of protecting the code. However none of them is ideal, obfuscation doesn't work with reflection when the string method/property names are used. Many people do not recommend to use obfuscation at all.

So I currently decided not to go with any of the above. However, I have parts of the code where I need a sort of encryption, for example, a database connection string with an IP, login and password is stored inside the code as simple const string, same as email account data.

In ASP.NET there is an option to move the sensitive data to a .config file and encrypt it, but that requires the server key, i.e. linked to a single computer. I didn't read much about it, but I suppose something similar is available for desktop applications. But I need this to work on any computer where the application is installed.

And here is the question: are there ways to encode/protect such data so that it cannot be read along with decompiled code?

like image 935
net_prog Avatar asked Oct 21 '11 12:10

net_prog


People also ask

What is the best way to protect sensitive data?

How can I protect Sensitive Data? Encryption is the most effective way to protect your data from unauthorized access. Encryption can be defined as transforming the data into an alternative format that can only be read by a person with access to a decryption key.

What is the best method to secure data in use?

The best way to secure data in use is to restrict access by user role, limiting system access to only those who need it. Even better would be to get more granular and restrict access to the data itself.


3 Answers

First advice is to never store anything sensitive in your code directly. You can always reverse engineer that, no matter how cleverly you try to obfuscate it.

I've read about things like breaking a password into several pieces, placing them at different places in the code and running them through a series of functions before finally using them... although this makes things harder, you can still always monitor the application using a debugger and ultimately you will be able to retrieve the secret information.

If I interpret your scenario correctly, what you have is code that is to be deployed at some client's premises and your code is connected to a database (which I suppose is also under the client's supervision), connecting to it requires a password. This password is known to that client, so trying to hide it from the client is rather useless. What you do want is to restrict access to that password from anybody who is not supposed to know it.

You typically achieve this by putting the sensitive information in a separate file in a folder that should have very restrictive permissions, only the application and a handful of selected people should have access. The application would then access the information when needed during runtime.

Additionally encrypting the separate file turns out to be a problem - if you do so then there is a key involved that again would have to be secured somehow - infinite recursion is on it's way :) Securing access to the file is often sufficient, but if you really require to be as secure as possible, then a solution is to use password-based encryption for the file. But the idea here is not to store the password in yet another location on the system, but rather as out-of-band information (e.g. in a physical vault) and entering the password when starting the application. This, too, has its problems: physical presence of a person is required for (re-)starting the application, and you could still retrieve the password from the RAM of the machine where the application is running on. But it is probably the best you can do without specialized hardware.

Another good alternative to password-based encryption would be to rely on OS-specific "password vaults" such as Windows' Isolated Storage, it's sort of a trade-off between not encrypting at all and keeping the password out-of-band.

like image 194
emboss Avatar answered Oct 05 '22 15:10

emboss


This isn't an encryption answer, but one way to 'secure' this would be to make all your database calls through a web service. Your connection credentials would then be stored on your secure server and the clients pass all calls through there.

Nothing sensitive stored in your re-distributable at all...

like image 24
Paddy Avatar answered Oct 05 '22 15:10

Paddy


I have grappled with this problem in the past and come up with three ways of dealing with the problem, but I'm not sure any of them are perfect:

  1. Obfuscate or encrypt the value and hope for the best. Encryption, of course, is just an extra level of obfuscation since the key must be delivered with the rest.
  2. Eliminate the need for the key itself by using one-way encryption instead. Use a private key to generate a public key. This can be used for licensing or password validation. You generate the licenses with the private key, but the public key can be used to validate them. Or you use the private key to generate a password that can be validated, but not reversed using the public key.
  3. Create your own system-specific key-generation mechanism similar to that used by ASP.NET. You can limit the effect of someone reversing the encryption/obfuscation in step 1 by generating a unique key for each installation or site.
like image 22
BlueMonkMN Avatar answered Oct 05 '22 16:10

BlueMonkMN