用RAIL为没有强签名的程序集签名

你是否有过这样的经历,你的程序集需要强签名,但是你引用的一个第三方程序集没有强签名,那么你也因此不能为你自己的程序集强签名了。你并没有第三方程序集的源代码,所以你无法给它签名,但是你的安全策略要求你发布的程序集必须有强签名,怎么办呢?

这的确是个很棘手的问题,幸好有一个折中的方法。我们可以这样,将第三方程序集引用的程序集签名(方法同正在描述的一样),然后将要签名的这个第三方程序集反编译为IL,将这个IL编译成新的一个程序集并给予签名。这样,我们就得到了一个有签名的第三方程序集,我们在自己的项目中引用这个有强签名的程序集,这样一来,我们就可以强签名自己的程序集了!^_^

上面的是理论,实现起来可能比较复杂,现在我们可以借助RAIL来简单的达到这个目的。对于不了解RAIL的朋友,RAIL是.NET下一个非常好的Code Instrumentation Library,它的能力很强,简单地说就是能够将一个程序集的IL结构转成(parse)成对象,然后基于对象操作整个程序集的结构,比如删除一个类型,在一个方法中插入另一个方法的指令等等。

我们这里会活用RAIL,用RAIL加载一个程序集然后什么都不做就保存为另一个程序集,但是我们会在保存时加入强签名。值得一提的是,RAIL最新的版本0.5.7并没有对强签名做实现,而且在保存方面还有一些不足,以下是一些它的问题:

  • 不能指定保存路径,自动保存到当前目录的上一级目录。不要问我为什么是上一级目录,我也不知道。
  • 不能控制PDB文件的生成,自动生成,这个我个人觉得很烦。
  • 没有实现强签名功能,保存后的程序集都是无强签名的。
  • 在使用过程中发现了一个读取程序集结构的bug,读取构造函数时没有区分是.ctor还是.cctor(分别为实例构造函数与静态构造函数),导致调用错误,引起错误的IL输出。

针对以上问题,如果不解决掉的话就会使RAIL使用起来不够自然,不够自信,所以我动手了解了一番RAIL的源代码,终于把以上问题解决了。我用这个改动后的RAIL将RAIL自身引用的一个DLL强签名了(没有源码),然后又重新编译了一个有强签名的RAIL^_^ 这样一来RAIL就可以在有强签名的项目中被引用了。使用改动后的RAIL实现保存时签名的代码如下:

// Load the original assembly.
string asmFileName = Environment.CurrentDirectory + "\\DotSets.dll";
RAssemblyDef dotSets 
= RAssemblyDef.LoadAssembly(asmFileName);

// Save as a new assembly with strong name.
dotSets.SaveAssembly(Environment.CurrentDirectory + "\\saved\\DotSets.dll"false@"E:\Work\Rail-Working\key.snk");

保存时的第一个参数为新程序集的路径,第二个参数为是否生成PDB文件,第三个参数为签名文件,如果指定为null的话就没有强签名。

我相信你一定也对RAIL感兴趣了吧,RAIL的能力很强,我准备用它实现一个AOP框架,目前还在需求挖掘阶段,有兴趣的并且代码规范执行的彻底的朋友可以联系我!:)

BTW,RAIL是葡萄牙的一所大学创建的,代码质量很差,不过技术能力很强。;)

在这里下载修改过的版本:https://files.cnblogs.com/cavingdeep/rail-modified-by-cavingdeep-v0.5.7.zip

License为Mozilla Public License 1.1

posted @ 2005-08-13 16:27  Cavingdeep  阅读(2707)  评论(17编辑  收藏  举报