.net中的如何私有部署强命名组件

私有部署:何谓私有部署这是相对公有部署而言的,我们知道在安装了dotNetFramework的机器上%SystemRoot%/assembly(%SystemRoot%一般指系统Windows目录)目录中的文件是.net运行必需的组件,然而在我们自己的可执行程序中需要的组件,存放在程序的根目录下的dll组件(也称作程序集文件)。对这些文件的部署就称为私有部署。当然也可以部署到公用程序集缓存中(也称作GAC,若要部署GAC不能单纯的把dll复制到assembly目录,这里需要一个部署工具GACUtil.exe,关于这个工具的使用请查看MSDN,这里不在详细阐述)程序运行需要调用的组件 部署在程序根目录下。后面我会讲到如何组织dll组件。

开始我们的正式行程:

以下内容提到的程序集文件,dll,组件意义相同。

I:组件的创建

Ⅱ:可执行体程序

Ⅲ:你可以发现我的!~!(dll私有部署到根目录下的任意文件夹下)

Ⅳ:没人可以替换我!(dll/exe强命名,使用公钥/私钥给程序集签名,防篡改) 

I:组件的创建

这里我们首先编译一个dll组件(这里的代码无任何实用功能,仅作演示)

命令行执行csc.exe /out:Utildata.dll /t:library /r:Dataprovider.cs

得到UtilData.dll文件

using  System;
using  System.Collections.Generic;
using  System.Text;

namespace  UtilData
{
    
public class DataProvider
    
{
        
public DataProvider() { }
        
public DataProvider(Int32 _id, String _name, String _sex)
        
{
            id 
= _id;
            name 
= _name;
            sex 
= _sex;
        }


        
private Int32 id;
        
private String name;
        
private String sex;

        
public Int32 ID
        
{
            
get return this.id; }
            
set if (value >= 0this.id = value; } }
        }

        
public String Name
        
{
            
get return this.name; }
            
set if (value != nullthis.name = value; } }
        }


        
public String Sex
        
{
            
get return this.sex; }
            
set if (value != nullthis.sex = value; } }
        }


        
public String GetDataProvider(Int32 id)
        
{
            
return "You id is:" + id.ToString();
        }


        
public override string ToString()
        
{
            
//return base.ToString();
            StringBuilder sb = new StringBuilder();
            sb.Append(
"My id:" + this.id);
            sb.Append(
"My name:" + this.name);
            sb.Append(
"My sex:" + this.sex);
            
return sb.ToString();
        }

        
    }

}

 

 Ⅱ:可执行体程序

创建winapplication窗体程序界面如下,添加引用,找到刚才生成的dll组件

Test按钮后台代码:

  // my code
        UtilData.DataProvider dp  =   null ;
        
private   void  btnCall_Click( object  sender, EventArgs e)
        
{
            dp 
= new UtilData.DataProvider(001"fang""man");
            MessageBox.Show(dp.ToString());
        }

生成项目,我们可以发现在项目debug目录结构如下:

Ⅲ:你可以发现我的!~!(dll私有部署到根目录下的任意文件夹下)

在实际应用中我们往往会吧dll组件分布在应用程序根目录下的不同文件夹下,我们应该如何做呢?

clr会找到运行时需要的组件吗?这就需要.config文件的支持了,在根目录新建一个和可执行程序同名的config文件,比如privatePublish.exe 的config文件文件名称为privatePublish.exe.config,clr在加载privatePublish.exe是会按照.config配置的信息运行程序。

privatePublish.exe.config文件,这里列的条目比较简单,详见MSDN,Lib就是存放dll组件的目录

如果有多个目录用分号分开(比如dll组件目录需要两个文件夹则privatePath="Lib;SupDll")clr会自动在寻找所需的程序集文件。

< configuration >
< runtime >
< assemblyBinding   xmlns ="urn:schemas-microsoft-com:asm.v1" >
< probing  privatePath ="Lib" />
</ assemblyBinding >
</ runtime >     
</ configuration >

目录结构

Ⅳ:没人可以替换我!(dll/exe强命名,使用公钥/私钥给程序集签名,防篡改) 

何谓强命名,一个强命名组件包含4个特性:组件名称,语言特性,版本,公钥标记,这4个特性可以唯一的确定程序集。

这里需要介绍个Sn.exe实用工具,它位于.net安装目录。(具体使用方法见MSDN)

我们的目的是要得到公钥标记,所以命令行执行

SN.exe -k myKey.keys          创建公钥/私钥对文件,程序集需要的就是它。

SN.exe -p mykey.keys mykey.publickey    依据公钥/私钥文件,创建公钥文件,为了下一步查看公钥 和公钥标记

SN.exe -tp mykey.pubilckey  控制台显示公钥和公钥标记  我的机器上运行此步骤截屏

要生产强命名的UtilData.dll文件执行如下命令行

csc.exe /out:Utildata.dll /t:library /keyfile:my.keys /r:Dataprovider.cs

这与之前生成的UtilData.dll唯一不同就是指定了keyfile:my.keys 开关。当然亦可以对exe文件添加添加同样的开关对exe也执行强命名

可以在项目属性属性—签名标签中指定keys文件对winexe文件签名

至此就完成了对程序集的私有部署+强命名

做个小试验验证下对强命名程序集的篡改会导致什么后果

Restorator 打开UtilData.dll,

点击保存~!我们对UtilData.dll进行了篡改。

我们运行PrivatePublish.exe   咯问题来了

为什么会这样呢,因为对程序集进行篡改了,修改的UtilData.dll的数据已经不能被调用它的程序集识别了,所以加载程序集出现了错误~!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值