没有强命名的代码签名是否会让您的应用程序被滥用?

时间:2011-12-19 19:56:30

标签: c# .net code-signing strongname authenticode

试图了解authenticode代码签名和强命名。

我是否正确地认为,如果我对引用一些dll(不是强名称)的exe进行代码签名,恶意用户可以替换我的DLL并以看起来好像是由我签名的方式分发应用程序,但正在运行他们的代码?

假设这是真的,看起来你真的不想在没有强烈命名整个事情的情况下签署.NET应用程序,否则你会让人们在你编写的应用程序的幌子下执行代码?

我不确定的原因是,我在网上找到的文章(包括关于使用SN + Authenticode的MSDN文档)都没有提到这一点,这似乎是一个相当重要的理解点(如果我是理解正确)?

4 个答案:

答案 0 :(得分:15)

  
    

我是否正确地认为,如果我对引用一些dll(不是强名称)的exe进行代码签名,恶意用户可以替换我的DLL并以看起来好像是由我签名的方式分发应用程序,但正在运行他们的代码?

  

是的,如果其余的DLL只是签名而不是强名称,则可以在不引发异常的情况下替换它们。您可以在exe内部验证DLL是否由与exe相同的密钥签名。这些方法都不能阻止某人替换您的DLL或EXE。

  
    

假设这是真的,看起来你真的不想在没有强烈命名整个事情的情况下签署.NET应用程序,否则你会让人们在你编写的应用程序的幌子下执行代码?

  

一般来说,我认为这是“最佳做法”,但你再次没有阻止任何事情。一旦用户有权更改本地系统上的文件,您就无法阻止他们进行恶意活动。

有几种混淆技术可以将完整的.NET项目构建到单个exe中,这可能会使“最安全”的方法仍然可以被篡改。

真正的问题是你想阻止他们做什么?我的意思是说,为什么有人会有兴趣更换你的dll?他们希望实现什么,他们的目标是什么?如果你试图阻止某人从你进入的过程中读取敏感信息,那就是一段漫长的艰难道路。假设恶意方可以完全访问您的源代码以及您的进程使用的每条信息,因为它们可以访问。假设他们可以随意替换全部或部分代码,因为他们可以。

<强>更新

  
    

因此,绑定重定向仅适用于使用相同键进行强名称的程序集,因此可以保护您免受更改的DLL的影响吗?

  

正确,除了注意到的例外,代码注入仍然可以通过多种方式完成。

  
    

...回到最初的问题,没有强命名的代码签名是否会破坏代码签名的重要性?

  

不是真的。代码签名(不强命名)有两个不同的目的:

  1. 认证。验证软件作者是谁。
  2. 完整性。验证软件自签署以来未被篡改。
  3. 通常只在安装过程中对其进行身份验证和验证。这就是我们签署setup.exe的原因,以确保客户已收到我们未经修改的安装程序。系统会提示“您信任XXXX公司”,从而授权经过身份验证/签名的安装程序。一旦安装,操作系统几乎没有内置的代码签名使用(除了驱动程序和其他一些模糊的情况)。

    另一方的强命名与它的存在有着完全不同的目的。它完全专注于应用程序的“完整性”。没有证书,没有签名机构(CA)来验证它,没有用户显示的信息供他们确认,操作系统也无法验证它将要运行的可执行文件。

    .NET框架对很多东西都使用了强名称,所有这些东西我都松散地归类为应用程序的完整性:

    1. dll / exe的内容有一个签名的哈希值,因此无法被篡改。
    2. 加载依赖项时,每个引用都必须强名称和验证。
    3. 可以在GAC中注册程序集,也可以使用发布者策略。
    4. 可以生成本机图像以生成程序集IL的编译图像。
    5. 我确信这里还有其他一些我不知道的东西,但这些是我所知道的主要用途。

      签名和强命名的最佳做法

      • 使用已签名的安装程序
      • 使用代码签名的可执行文件
      • 使用强名称的可执行文件
      • 强名称所有依赖项及对它们的引用
      • 通常不需要代码签名依赖项*
      • 考虑GAC在安装时注册程序集

      *注意:代码签名在某些情况下对于DLL很有用,例如标记为“安全”并嵌入浏览器的COM对象应该签名并强名称,就像它是可执行文件一样。代码签名在外部验证依赖关系时也很有用,无需加载程序集或反映它的属性。

答案 1 :(得分:1)

一旦有人可以替换你的机器上的dll或运行代码,就不会有很多安全措施留给你。就我而言,所有Dll都是单独签名的代码。我的代码拒绝下载未作为自我更新的一部分签名的Dll。但是,在我的系统上以我的完整性级别或更高级别运行的任何应用程序(在&gt; = Vista Windows的情况下)仍然可以通过CreateRemoteThread等(http://www.codeguru.com/Cpp/)向我的exe中注入一个dll WP / DLL / article.php / C105) 但再次假设某人可以将外国代码输入系统是困难的部分。其余的很容易。

答案 2 :(得分:0)

你还必须记住,在不部署应用程序的其他部分的情况下升级dll时,代码签名经常会带来很多痛苦。

这就是为什么许多流行的图书馆都没有强烈命名dll的

答案 3 :(得分:0)

在搜索相同内容并阅读许多内容之后。我终于可以对你的问题说,是的,如果要对应用程序执行数字签名,必须使用依赖项的强名称。

如果你的依赖关系没有强名,请假设这一点。他们被取代了。您的应用程序将毫无问题地加载它们。用户将看到对话框&#34; Verified Publisher:Your Name&#34;。虽然可执行文件未受影响,但依赖项已被更改。

问题不在于该用户,而是分发了具有更改依赖关系的包,而每个人都会在其上看到您的名字。