使用强命名程序集防范篡改

CLR支持两种程序集:强命名程序集、弱命名程序集,两者的区别在于,强命名程序集是被发布者使用了自己的公钥/私钥对进行了程序集的签名,能唯一性标识程序集的发布者的程序集,并且可以使用密钥对程序集进行唯一性标识、保护和版本控制,这里所提到的保护就是我们需要一起讨论的程序集防篡改。

  首先我们一起来看个例子,这样能简单明了地说明使用强命名程序集的必要性。

  我们建立一个WinForm程序Nick.WinFormApp,添加一个登录窗体,并且在此项目内引用名为Nick.AuthProvider的程序集,用于登录的时候进行身份验证。

  


在Nick.AuthProvider程序集中添加类AccessHandler.cs,用于实现身份验证过程,代码如下  

复制代码
namespace Nick.AuthProvider
{
///<summary>
/// 作者:MitnickZhou
/// 出处:http://www.cnblogs.com/mitnickzhou/
///</summary>
public class AccessHandler
{
public static bool CheckValid(string userName, string passWord)
{
if (userName.Equals("Nick") && passWord.Equals("Zhou"))
{
return true;
}
return false;
}
}
}
复制代码


并在LoginForm中添加如下代码,用于显示登录结果,只有当我们在登录窗体中,输入用户名:Nick,密码:Zhou 的时候,系统才会让我们登录成功。

复制代码
        private void btnLogin_Click(object sender, EventArgs e)
{
string resultMsg =
AccessHandler.CheckValid(this.txtUserName.Text, this.txtPassWord.Text).ToString();
MessageBox.Show(resultMsg);
}
复制代码



  好,假如这时我们的程序已经开发完成,可以将其发布出去了,编译之后需要发布的文件如下:
  

  运行程序,输入用户名和密码,并点击登录,如我们所期望的那样,只有输入了正确的用户名和密码后,程序才会提示登录成功。那么假如说其他别有用心的人,知道了Nick.AuthProvider.dll这个程序集的作用之后,可以做什么事情呢?我们一起来看看。 


  重新建立一个新的程序集,取名也叫做Nick.AuthProvider,并且添加AccessHandler的类型。  

  


  AccessHandler内的代码如下,对于任意用户名和密码,都返回验证通过。

复制代码
    public class AccessHandler
{
public static bool CheckValid(string userName, string passWord)
{
return true;
}
}
复制代码

  

  现在我们将编译后的Dll替换之前我们已经发布的Nick.AuthProvider.Dll,再运行程序,大家看看将是什么效果。  
  我们输入任意的用户名和密码  

  

  得到的登录结果就和我们预期的不一致了,任意用户名和密码都能登录成功。
 

  那么我们如何避免上述问题的发生呢?毕竟程序发布之后,我们的控制能力是有限的,一般来说可以通过代码混淆来进行一定保护,也可以通过ILMerge进行程序集的合并,以避免别人知道你的程序集结构,但是为了要避免这种程序集的替换,我们就可以使用强名称程序集来搞定。

  要为程序集分配强名称,操作上是相当简单的,分为命令行方式和IDE方式,这里我们就介绍使用IDE来对程序集进行强名称,步骤简单,我也就不截图了。
  1:在需要分配强名称的程序集上,右键-属性
  2:切换到“签名”页签,勾选“为程序集签名”
  3:从“选择强名称密钥文件”框中选择“<新建>” 

  接下来重新编译Nick.WinFormApp工程,将自动使用已经分配了强名称的程序集Nick.AuthProvider,那么我们再次模拟一下发布之后的DLL替换操作,运行程序之后,输入用户名和密码,点击登录,将得到以下错误提示。  

  
  可见为程序集添加强名称后,已经不能使用这种替换的方式来修改我们已发布的程序了。
  但是程序的保护不仅仅只有这一方面,而且就算是强名称签名后的程序集也是可能被去除掉强名称的,需要配合代码混淆,IL合并以及其他加密方式来进行程序的保护。
  
  注意:
    1:强命名程序集无法引用没有强名称的程序集(.net框架所有程序集都是强命名的) 
    2:强命名程序集的机制只能保证文件的内容没有被篡改,而无法让用户知道程序集的发布者是谁。
    3:请妥善保管好自己的snk签名文件

作者:MitnickZhou
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/aaa6818162/p/4732301.html