.Net 程序集安全 - 防止黑客攻击/逆向工程
我将知识产权编码到最终用户计算机上的 .net 2.0 完全受信任的程序集(.exe + DLL)中,我希望保护它免遭黑客攻击/逆向工程(Web 服务/云计算解决方案不是一个选项)。以下是我为实现这一目标而收集的技术列表。
我的问题是:
- 我的假设是否正确,或者我在一项或多项技术中做错了什么?
- 此列表足以防止恶意攻击吗?或者我还应该添加其他保护措施吗?
提前致谢。
--
建议的技术
- 使用相同的强名称密钥对所有程序集进行签名。
这有两个好处:- A.确保对程序集的任何修改都会使其变得无用,
- B.所有程序集都将具有相同的公钥,通过该公钥它们可以相互识别。
- 对程序集进行数字签名:两者都让用户知道执行的代码来自正确的源,并且 - 添加另一个标识组件,程序集可以通过该组件相互识别。
- 通过爬取调用堆栈并验证所有调用者都在“社区”内来执行上述操作。
可能的线索:- Hallgrim 在这个 SO 帖子中的想法.
- Daniel Brückner 在此 SO 主题中添加的内容。
- 此.Net 安全博客文章,它结合了两种解决方案。
- 使用AOP(例如Spring.NET)将调用堆栈爬取代码注入到某些/所有方法中。
- 这样做主要是因为 .net 程序集中没有单一入口点(例如 Win32 DLL 的 DllMain())。
- 混淆所有程序集,以阻止逆向工程和反射执行尝试(当然,强名称签名将在混淆后执行)。
- 集成 System.ComponentModel.LicenseProvider 机制。
- 利用“InternalsVisibleTo”程序集级属性来公开一组预定义的程序集之间的内部结构。
- 可能使用 NGEN 将解决方案转换为本机代码。
考虑要点
- 实现上述部分或全部内容很可能会带来性能损失,因此,例如,时间关键型处理应谨慎处理。
- CAS 似乎与这种完全可信的程序集无关。
I have intellectual-property coded into .net 2.0 fully-trusted assemblies (.exe + DLLs) on an end-user machine, which I would like to protect from being hacked / reverse-engineered (WebService / Cloud-Computing solutions are not an option). Below is a list of techniques I gathered in order to reach this goal.
My questions are:
- Are my assumptions correct, or am I doing something wrong in one or more of the techniques?
- Will this list be sufficient in order to prevent a malicious attack, or are there other protections I should add?
Thanks in advance.
--
Suggested Techniques
- Sign all assemblies with the same strong-name key.
This has two benefits:- A. Make sure any modification to an assembly will render it useless,
- B. All assemblies will have the same public key, by which they can identify each other.
- Digitally sign the assemblies: Both let the users know that the executed code came from the correct source, and – add another identification component by which assemblies could identify each other.
- Enforce the above by crawling up the call-stack and verifying that all callers are inside the “community”.
Possible leads:- Hallgrim’s idea in this S.O. thread.
- Daniel Brückner‘s addition in this S.O. thread.
- This .Net Security Blog Post, which combines both solutions.
- Use AOP (e.g. Spring.NET) to inject the call-stack crawling code into some/all methods.
- This is mainly done because there’s no single entry point (like DllMain() for Win32 DLLs) in a .net assembly.
- Obfuscate all assemblies in order to hamper reverse-engineering and reflection-execution attempts (strong name signing will be performed after obfuscation, of course).
- Integrate a System.ComponentModel.LicenseProvider mechanism.
- Make use of the “InternalsVisibleTo” assembly-level attribute in order to expose internals among a pre-defined set of assemblies.
- Possibly use NGEN in order to convert the solution to native code.
Points to Consider
- Implementing part or all of the above will most-likely introduce a performance penalty, so time-critical processing, for example, should be handled with care.
- CAS seems to be irrelevant for this type of fully-trusted assemblies.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我担心你得不到你想要的所有安全感。您会看到,这是使用中间语言的这些语言/平台的问题。它必须采用所有运行时实现都可以使用并生成本机代码的格式。
我看过一些关于篡改签名程序集的博客文章。我还没有尝试过,但我认为它有效。除此之外,混淆工具只会使提取代码变得更加困难,但并非不可能(尽管有一些非常好的工具使提取代码变得非常困难)。 NGEN 不适合这个。您仍然需要分发原始程序集。
我认为保护代码最有效、最安全的方法是将其转移到无法反编译的技术,例如,将敏感代码转移到非托管 C++ 并在 C# 代码上使用 DLLImport。
这并不意味着您不应该尝试保护您的代码,但您应该记住您不会得到 100% 的保护。如果您无力用另一种语言重写敏感代码,请使用混淆和签名。没有比这更安全的了。
I'm afraid you won't get all the security you want. You see, this is a problem with these languages/platforms that use an itermediate language. It must be in a format that all of the runtimes implementations can consume and then produce the native code.
I've seen some blog posts about tampering signed assemblies. I haven't tried yet, but I think it works. Besides that, the obfuscation tools will just make it harder, but not impossible to extract code (altough there are some pretty good tools that make it very hard). And NGEN is not for that. You still have do distribute the original assemblies.
I think that the most efective and secure way of protect your code, is to move it to a technology that you can't decompile, for example, move your sensitive code to unmanaged C++ and use DLLImport on your C# code.
It doesn't mean that you shouldn't try to protect your code, but you should have in mind that you won't be 100% protected. If you can't afford to rewrite your sensitive code in another language, go with obfuscation and signing. You can't get much more secure than that.