2010-02-02 23 views
3

我已经复习了.NET Strong Name过程几次并认为我对此感到满意,但是我仍然留下了我认为是安全漏洞的东西:如何验证程序集是由我的组织签署的?

我正在研究一个系统,我们将序列化的.NET程序集存储在我们的MS SQL数据库中。它们由面向公众的Web应用程序读取,并将其反序列化并缓存。这是为了允许远程添加新插件而无需重新部署Web应用程序。

然而,我有一些关于作者验证的问题。 Web应用程序和插件程序集都使用相同的公钥和私钥生成强名称。这样一来,我保证该插件不能被篡改的,但我看到其中一个恶意用户可以执行自己的代码一个场景:

  1. 用户实现实现该接口插件我们的组件正在使用(这是非平凡的,因为插件不是分布式的 - 我们在内部创建它们)。
  2. 用户提供了这个组件的强名称自己
  3. 用户管理注入其装配到相应的表中我们的数据库
  4. Web应用程序负载的情况下安装和实例的构造函数接口恶意用户实施 - 它现在正在执行他们的代码

这是我的理解,.NET框架将只检查程序集有一个强名称,并没有被篡改 - 它没有说任何关于验证的作者。

因此,我的最后一块难题是以某种方式验证程序集中的签名实际上是我们自己的。我是否错过了一些已经解决的基本问题,还是错误的命名不是为了处理这种情况?如果是这样,任何人都可以建议如何解决这个问题? [编辑] 谢谢哈立德!我的问题是,我的一个测试插件是使用测试密钥签名的 - 我已经重新生成了它(不问),并将其应用于其他程序集,但错过了那个。因此,我认为GetPublicKey()返回的是不一致的值!

的代码段的人谁是这条路:

private bool ValidateAssembly(byte[] deserializedAssembly){ 
    byte[] ourKey = Assembly.GetExecutingAssembly().GetName().GetPublicKey(); 
    for (int i=0; i < deserializedAssembly.Length; i++){ 
     if (deserializedAssembly[i] != outKey[i]) 
     return false; 
    } 
    return true; 
} 

(为清楚起见移除任何错误处理或不公钥检查)

注意,只要这个工程作为执行组件(网应用程序)和插件使用相同的密钥进行签名。这对我们在内部很有用,但是如果你的插件API是公开的,你需要一种不同的方式来管理信任。

+0

这应该是代码第4行的'我们的关键'吗? – ovinophile 2010-02-02 19:39:18

回答

3

你的攻击听起来似乎很合理,直到我大声朗读这句话。

用户管理注入其装配到相应的表中我们的数据库

如果黑客能够访问你的数据库,我想这是不是担心他会在代码一个更大的问题正在执行。但无论如何,下面是一些代码来获取您可能加载的程序集的公钥。你可以检查你的钥匙,并确保它不是其他签名。

AssemblyName asmName = asm.GetName(); 
byte[] key = asmName.GetPublicKey(); 
bool isSignedAsm = key.Length > 0; 
Console.WriteLine("IsSignedAssembly={0}", isSignedAsm) 

AssemblyName类应该为您提供足够的信息来解密您的签名是否与您提供给人的密钥匹配。

现在,如果黑客有你的钥匙(公共/私人),那么他正在从内部工作,这是一个更大的问题。

相关问题