你可以使用signcode.exe将证书应用到一个程序集。这个工具将证书欣到DLL的一个众所周知的位置,并且计算出一个数字签名以防止篡改。程序集加载器在加载时将注意到该证书,并且,为被加载的程序集附上一个Publisher证据对象,下面的代码演示了如何基于一个从磁盘加载的原始X.509证书构造一个Publisher证据对象:
证书的前三个属性(Name,IssuerName和ExpirationDate)传达了大数开发者和系统管理员所关心的信息,其余的属性则是为了防止那些技术痴迷者睡不着觉,并且已经超出了本书的范围,这里就不做讨论了。
我们将要讨论的最后一种证据类型是Hash证据类型。Hash证据只是一个精简的标识符,用于惟一地标识组件的特定编译版。程序集加载器将Hash证据添加到所有的程序集,使得安全策略能够识别一个程序集的特定生成,即使当程序集版本号没有改变时也是如此。
CLR定义了一个内置类型(sysem.Security.Policy.Evidence),用于控制由安全策略所使用的证据。Evidence类型自身是一个简单集合,它实现了System.Collections.ICollection
接口。但Evidence类型与普通集合的不同之处在于,它有两个内部集合:一个用于内置宿主证据对
象,另一个用于用户自定义程序集证据对象。
下面的代码演示了如何构造一个新的包含Url、Zone和Site证据的Evidence对象:
using System;
using System.Security.Policy;
class App{
static void Main(string[] argv){
//接收作为命令行自变量的codebase url
string codebase=argv[0];
//创建并产生一个Evidence对象
Evidence evidence=new Evidence();
evidence.AddHost(new Url(codebase));
evidence.AddHost(Zone.CreateFromUrl(codebase));
try{evidence.AddHost(Siste.CreatePromUrl(codebase));}
catch(ArgumentException){/*忽略*/}
//显示相应的位值
foreach(object part in evidence){
Console.WriteLine(part);
}
}
}
当运行基本代码URL http://www.microsoft.com/foo.dll.程序的输出结果如下所示:
注意,每个证据对象都发射一个其自身基于XML的表示。这种语法的用途将会在本章后面解释。
以可编程的方式构造证据对象有时候是很有用的,不过,程序集加载器才是这个实用部件的主要使用者。通过System.Reflection.Assembly.Evidence属性,程序集加载器使程序集的证据对于安全策略和程序员是可用的。通过下面的代码片断,你可以了解到对于任意对象的程序集如何访问其证据:
using System.Reflection;
using System.Security.Policy;
public sealed class Util{
public static Zone WhichZone(object obj){
Evidence ev=obj.GetTyep().Module.Assembly.Evidence;
IEnumerator i=ev.GetHostEnumerator();
while(i.MoveNext()){
Zone zone=i.Current as Zone;
if(zone!=null) return zone;
}
return null; //非零
}
}
正如你将在整章看到的那样,证据主要被安全策略使用,程序员很少显式地访问它。sp; }
}