How secure are Resources in .NET?
How hard would it be to retrieve embedded resources from a .NET application, from outsid开发者_运维技巧e the application itself? Even if the resources are compressed and trivially encrypted, how difficult is it to retrieve them using a tool? (I am not concerned with the protection of the data per se, just the methods of retrieval of the resource itself)
EDIT:
I think my question was misunderstood, it was less about the encryption and more about the retrieval, other than reflector, what else can be used?
It is trivial to retrieve resources from a compiled .NET DLL using tools like the .NET Reflector or .NET Resourcer.
If you encrypt the resources with a key that is embedded in the application, then it will be easy to retrieve the key, and therefore the resources, with a bit of reverse engineering.
If you encrypt them using a secure algorithm and ask the user to enter the password, then without the password it won't be possible to extract the resources. But I guess that's not what you want. I guess you want to prevent the user from using your resources outside the application?
If so the short answer is: resources in .NET are not secure.
Here is some quick code to get resources out of Assemblies. You decide how easy and secure it is...
class Program
{
static void Main(string[] args)
{
var assemblies = from file in args
let assembly = TryLoad(file)
where assembly != null
from rName in assembly.GetManifestResourceNames()
select new { assembly, rName };
foreach (var item in assemblies)
using (var rs = item.assembly
.GetManifestResourceStream(item.rName))
SaveTo(rs, item.rName);
}
static void SaveTo(Stream stream, string name)
{
var buffer = new byte[32*1024];
var bufferLen = 1;
using (var fs = new FileStream(name, FileMode.Create))
while (bufferLen > 0)
if ((bufferLen = stream.Read(buffer, 0, buffer.Length)) > 0)
fs.Write(buffer, 0, bufferLen);
}
static Assembly TryLoad(string filename)
{
if (string.IsNullOrEmpty(filename) ||
!File.Exists(filename))
return null;
try
{
var fullName = Path.GetFullPath(filename);
return Assembly.LoadFile(fullName);
}
catch (Exception ex)
{
Debug.WriteLine(ex);
return null;
}
}
}
The problem is less about .NET resources and more about security in general. You could rephrase the question as "my client application stores secrets that I don't want reverse-engineered" and not change the intent.
What is in your resource files, and why does it need to be secured? Have you considered a design in which you don't store those secrets on the client at all? If you're banking on keeping client-side secrets secure, I think you'll be disappointed.
If I show you a safe with a million dollars in it, then walk away, you will eventually get into that safe. There is no technology that will protect that money, your only real barrier is time.
It is the same for software. The only way to protect resources is to not place them where someone can, given enough time, get to them. The most effective option I know is storing the critial resources on a server that you control.
Of course many people get this wrong. One way or another, they allow the secure resource to be temporarily copied to the user's computer. At which point, the game is lost. This means you can only truly secure resources that have a natually temporary clone. For example, a security token that expires or the results of calcuation that don't reveal how the calculation was made.
精彩评论