摘要本文描述了如何用Code Access Security技术来保护代码使代码不致被恶意调用 作为一名NET开发人员你没日没夜地写代码你的组件运行在越来越多的机器上忽然有一天你发现你写的组件被引用在别人写的项目里而且最可气的是那人竟用你的名义在做破坏它人系统的恶事!你忍不住了大叫一声Oh shit!然后打开MSDN看看有什么办法能帮助你阻止这场阴谋 OK办法找到了那就是NET平台提供的Code Access Security有大量继承于CodeAccessPermission的类可以帮你实现不同方面不同范围的代码安全控制你所需要做的只是从中挑出最适合的类别加以应用从而达到保护你的组件的目的 在经过一番挑选之后你最终确定了使用StrongNameIdentityPermissionAttribute类这个类允许你将组件(或类方法)与某一强名称(通常就是你发布程序时所用的强名称)绑定这样只有在客户端程序具有该强名称签名的情况下才能使用你的组件也就是说除了你自己编写的客户端代码因为拥有同样的签名而被允许使用组件以外任何第三方代码都无法通过StrongNameIdentityPermissionAttribute的防护因此也就无法恶意调用你的组件了)听起来真的不错马上就动手做吧! 为了简便起见先创建一个很简单的Class Library项目代码如下 // SecureCompdll using System namespace musicland { public class SecureComp { public string Confidential() { return This is confidential! } } } 现在的这个组件非常可怜因为任何人都可以写代码来调用它下面你就要耍点手段了) 首先引入SystemSecurityPermissions命名空间 using SystemSecurityPermissions 然后在组件级加上StrongNameIdentityPermissionAttribute属性 [assembly StrongNameIdentityPermissionAttribute(SecurityActionRequestMinimum PublicKey=ccd+ fddbbadfcedddccedacbceaeecdf+ debcabfafcbfafbbcefbeeffcebfdf+ aacfccadbdeeacccacbafcacfebeab)] namespace musicland … 注意这里使用了SecurityActionRequestMinimum这申明除非获得StrongNameIdentityPermissionAttribute所表明的资源访问权限(即对SecureCompdll组件的访问权限可以把SecureCompdll看作一样资源)否则CLR不会准许调用方(即客户端代码)访问所请求的资源此外在PublicKey属性中加入了你所允许的公匙(Public Key)的十六进制表示(转化成字符串类型)CRL在运行期间将依照这一段公匙来判断调用方是否合法除非调用方拥有相应的私匙(Private Key)否则将无法访问看来平时一定要倍加保护你的密钥文件因为密钥文件(特别是private key)的洩露将会成为你无尽恶梦的根源而延迟签名(delay signing)在这里也就显得格外重要了) 说到这里你一定会有个大大的问号这长长的一串PublicKey是怎么得出来的?难道要我凭空凑出来不成?当然不是还记得那个Snexe工具吗?通过它就可以把PublicKey给提取出来OK打开你的命令行定位到密钥文件所在目录并输入以下内容 sn –p Keysnk PublicKeysnk 这样提取出来的公匙信息就被存储在PublicKeysnk文件中你现在只需把公匙信息读取出来并转化成适当的格式就可以了这里你可以使用NET Framework自带的Secutilexe工具但据我所了解Secutil工具的输出都是数组格式(我在自己的机器上测试了Secutil所提供的全部输出选项但所得结果都是一样这让我很感意外不知大家是否有更好的办法)因此就动手自己写了一个小工具来完成这一读取和转换大家如果感兴趣可以发邮件给我(因为我没有自己的网络空间可以存放当然你也可以自己来写因为它实在是太简单了就是读取二进制文件) 好了现在你的代码就被全副武装起来了试着写一个Console客户端来调用SecureComp结果怎么样?是不是无法获得相应权限?试着用Keysnk给客户端程序签名后再访问这回可以访问了吧!) 结论适当地应用Code Access Security可以使你的代码被保护起来不致被第三方不正确调用但是过多的安全保护也将造成代码运行效率下降从而带来负面影响 |