为通过ClickOnce部署的应用程序进行数字签名

ClickOnce是.NET用于Windows应用程序的一种便捷部署方式。不过由于便捷,导致缺少自定义操作的空间。比如需要对通过ClickOnce部署的应用程序的主程序(exe文件)进行数字签名就比较麻烦。下面简单分享下,在既能获得ClickOnce的便捷功能(包括VS自动生成ClickOnce部署包)的同时,又能方便的对应用程序进行签名。

1,为什么要进行数字签名

为了保证系统的安全,现在Windows(比如Windows 8)对于通过网络上下载的应用程序的执行文件都会首先阻止,并提示用户是否要运行。这个时候,同时会提示这个应用程序的发行者。如果一个没有进行数字签名的应用程序,这个时候发行者就为“未知”,签名后,就可以告知用户这个应用程序是由你提供的。在这里,数字签名就是保证这个应用程序是由你发行,并未被第三方更改的。

上面这种情况还好,很多时候,如果你安装了360之类的软件,对于未签名的应用程序,大部分情况是阻止其运行的。如果没有进行数字签名,那么对用户会造成极大困扰。

对执行文件进行数字签名还有诸多好处,我就不一一例举。现在购买一个代码签名的证书也不算贵,对于类似我们这种发行客户端应用程序的厂商而言,是很有必要购买一个证书的。

2,几个误解:程序集强签名、ClickOnce清单签名、安装程序签名

程序集强签名

.NET里面有个概念——程序集强签名。这个只是.NET可以使用这个强签名文件(snk)来对程序集进行签名,保证程序集本身不被篡改。以便保证其他人引用的这个程序集是你开发的。MSDN这样描述:

程序集签名(也称为强名称签名)赋予应用程序或组件一个唯一标识,其他软件可用该标识来显式标识和引用该应用程序或组件。强名称由程序集的简单文本名、版本号、区域性信息(如果提供)以及公钥/私钥对组成。

例如,强命名使应用程序作者和管理员可以指定用于共享组件将使用的一种准确的服务的版本。这使不同的应用程序指定不同的版本,而不会影响其他应用程序。 此外,还可以使用组件的强名称作为安全证据生成两个组件之间的信任关系。

要对程序集进行强签名,无需使用购买的代码签名数字证书,用.NET提供的sn工具就可以生成snk文件,你只要保存好这个文件,就可以保证你的程序集的签名。

但是,程序集强签名并不等于执行文件的数字签名(就算这个程序集是一个exe文件)。并且MSDN中明确说不应该对exe文件进行强签名(虽然我是这样做的)。文件的数字签名实际上是在文件系统级别对任何文件附加一个签名,告知操作系统此文件的发行者是谁。即可以在文件的属性对话框中,看到“数字签名”这项选项卡。

ClickOnce清单签名

另外,对于ClickOnce的应用程序清单(即app.exe.manifest文件)和部署清单(即app.application文件)进行签名。这样的签名实际上保证客户端正确识别ClickOnce部署包的发行者以及完整性,保证不被第三方篡改。如果不对ClickOnce清单进行签名的话,那么在安装(即运行app.application文件)的时候,安装程序就无法显示发行者,在某些企业环境下或某些安全软件下,就可能阻止application文件的运行(尤其你的应用程序需要获取Full Trust权限的时候更是如此)。但是,对于ClickOnce清单进行签名并不会对程序的执行文件进行签名(虽然同样需要代码签名数字证书)。

安装程序签名

使用过ClickOnce部署的同学,应该知道VS在生成ClickOnce部署包的时候,会同时生成一个setup.exe文件。同样,ClickOnce不会自动对这个按照执行文件进行签名。为了保证这个setup.exe能顺利的在客户端机器上运行,最好还是对其进行数字签名。MSDN文档中就有一节内容专门讲述了这个问题——“How to: Sign Setup Files with SignTool.exe (ClickOnce)”。同样,就算setup.exe被签名了,应用程序真正的执行文件还是需要签名的。

当然,正因为有了SignTool这个工具。

3,失败尝试:Post-Build Events

由于我生成ClickOnce部署包,是完全依赖于VS来自动生成的。所以为了最大限度的保证这种自动化,我首先尝试在Post-Build Events中对编译出来的exe程序集(bin文件夹内的)进行签名。不过后来发现,ClickOnce是从obj文件夹里面复制文件;随后对obj中的程序集进行签名,结果ClickOnce包含的程序集还是未签名的。我估计,ClickOnce在打包前会对程序集进行hash检查,如果hash不对,就会自动全新编译(跳过Build Events的执行)。经过几次尝试后,最后还采用ClickOnce打包完成后,再来签名的方法。

4,最终做法:用CMD脚本对ClickOnce部署包进行处理

在重新复习了ClickOnce的一些重打包的命令之后,编写了如下命令行脚本,可以对ClickOnce打包好的部署包中的exe文件进行签名:

   1:  SET _dir=%CD%
   2:   
   3:  ECHO %_dir%
   4:   
   5:  rename eBalance.exe.deploy eBalance.exe
   6:   
   7:  signtool.exe sign /sha1 F0B5D453FE821F3DA370B87933BXXX /t http://timestamp.comodoca.com/authenticode eBalance.exe
   8:   
   9:  mage -update eBalance.exe.manifest
  10:   
  11:  mage -sign eBalance.exe.manifest -ch F0B5D453FE821F3DA370B87933BXXX -ti http://timestamp.comodoca.com/authenticode
  12:   
  13:  rename eBalance.exe eBalance.exe.deploy
  14:   
  15:  cd ..\..
  16:   
  17:  signtool.exe sign /sha1 F0B5D453FE821F3DA370B87933BXXX /t http://timestamp.comodoca.com/authenticode setup.exe
  18:   
  19:  mage -update eBalance.application -appm "%_dir%\eBalance.exe.manifest"
  20:   
  21:  mage -sign eBalance.application -ch F0B5D453FE821F3DA370B87933BXXX -ti http://timestamp.comodoca.com/authenticode
  22:   
  23:  xcopy eBalance.application "%_dir%\eBalance.application"

对上面的脚本简单解释一下:

5行,由于我打包部署的时候,包含了deploy后缀,所以先进行了一个重命名操作

7行,对exe执行文件进行签名,使用的是我安装在本机中的签名证书

9行,更新应用程序清单(即这个应用程序会包含哪些程序集、资源和其他文件)

11行,对应用程序清单重新签名

13行,把exe文件改回deploy后缀,以便接下来更新部署清单的时候能正常执行

17行,对setup.exe进行签名(可选)

19行,更新部署清单,且指明对应的应用程序清单是那个

21行,对部署清单重新签名

23行,用更新且重新签名的部署清单覆盖具体版本目录里面的部署清单

这段脚本需要进入到具体的部署版本目录里(比如:publish\Application Files\eBalance_4_1_13054_7),才能执行。

5,可选做法:手动生成ClickOnce部署包

当然,通过利用signtool、mage工具,你可以编写一段更加复杂的脚本(甚至使用PowerShell),来完全用脚本执行签名、生成相关清单,打包的工作。具体可以参考MSDN文档:http://msdn.microsoft.com/zh-cn/library/xc3tc5xx.aspx

为通过ClickOnce部署的应用程序进行数字签名的更多相关文章

  1. 获取使用ClickOnce部署的应用程序的版本号

    引子 在编写使用ClickOnce部署的应用程序时,需要在程序的标题栏.软件变更记录.软件关于等页面读取显示当前的版本号. 之前很傻瓜的做法就是在Resource中维护一个string值,在使用到的地 ...

  2. 以管理员身份启动ClickOnce部署的应用程序

    ClickOnce方式部署应用简单方便,估计很多人都用过,但这种方式存在一定的“缺陷”,即以管理员方式启动应用的问题,虽然出于安全考虑可以理解,但给需要管理员权限才能正常运行的程序带来了一定的麻烦,这 ...

  3. ClickOnce部署疑难杂症:更新时部署与应用程序标识不一致问题。要安装此应用程序,请修改此文件的清单版本或卸载之前存在的应用程序。

    使用ClickOnce部署winform应用程序.无论是安装或者自动更新都极为方便,但有时候一些疑难杂症也令人头疼 1.注意每次部署完成之后 setup.exe无需覆盖,只需要在Application ...

  4. C# ClickOnce部署WinForm程序

    之前做过ClickOnce部署应用程序的项目,今天做一次全面的总结.那么这些都是微软提供方便分布式部署的相关解决方法,这种方法既有弊端,也有优点. 最大的缺点: 远程部署,不能更换安装目录:并且每次安 ...

  5. 使用ClickOnce发布Windows应用程序

    前言 因本人工作需要,在一名非常非常好的老师的指导下,入门了C#,再次向老师表示感谢. 本人平时经常遇到的业务就是将数据下发给各部门,并让各部门再上报,此过程中经常会遇到数据格式不正确,数据错误等诸多 ...

  6. 转:ClickOnce部署Winform程序的方方面面

    1. ClickOnce简介 微软官方对ClickOnce的解释是:ClickOnce 是一项部署技术,您可以利用这项技术来创建基于 Windows 的自行更新的应用程序,并且安装和运行这类应用程序所 ...

  7. ClickOnce部署

    (1):一些发布方式 ClickOnce是什么玩意儿,这个问题嘛,在21世纪的互联网严重发达的时代,估计也没有必要大费奏章去介绍了,弄不好的话,还有抄袭之嫌.因此,有关ClickOnce的介绍,各位朋 ...

  8. ClickOnce部署(5):自定义安全权限

    今天我们来探讨一下在ClickOnce部署中如何严格控制应用程序的权限. 演示应用 为了在下文中能更好地演示,我们先要做一个测试项目.也为了显得简单易懂,我使用最常用且最常见的WinForm项目,这是 ...

  9. ClickOnce部署(4):下载多个安装包

    有时候,我们可能会一次性发布多个安装包,当然在网页上多加几个链接让用户逐个安装也是可取的.不过,也可以弄得更方便些,即用户先安装一个,作为一个"引导程序",然后通过这个程序去下载安 ...

随机推荐

  1. VirtualBox更改虚拟机磁盘VDI的大小

    流程虚拟机中使用,有时会遇到磁盘大小是不够的,假设一套"动态分配的内存".通过下面的方法来手动扩展磁盘空间. 1.启动CMD命令行.进入VirtualBox安装文件夹.例如 cd  ...

  2. CreateMutex

    C++ API CreateMutex 找出当前系统是否已经存在指定进程的实例.假设没有则创建一个相互排斥体.CreateMutex()函数可用来创建一个有名或无名的相互排斥量对象. HANDLE C ...

  3. WPF应用程序支持多国语言解决方案

    原文:WPF应用程序支持多国语言解决方案 促使程序赢得更多客户的最好.最经济的方法是使之支持多国语言,而不是将潜在的客户群限制为全球近70亿人口中的一小部分.本文介绍四种实现WPF应用程序支持多国语言 ...

  4. EditPlus仿Sublime配色方案(三种任你选择)

    [Options] Placement=2C00000002000000030000000083FFFF0083FFFFFFFFFFFFFFFFFFFFEA000000EE000000D6050000 ...

  5. 快速构建Windows 8风格应用30-应用生命周期管理

    原文:快速构建Windows 8风格应用30-应用生命周期管理 引言 Windows 8 中可以启动多个应用并在其中切换,我们没有必要担心降低系统速度或消耗电池电量. 因为系统会自动挂起(有时会终止) ...

  6. Java集合之HashMap源码实现分析

    1.简介 通过上面的一篇随笔我们知道了HashSet的底层是采用Map实现的,那么Map是什么?它的底层又是如何实现的呢?这下我们来分析下源码,看看具体的结构与实现.Map 集合类用于存储元素对(称作 ...

  7. STM32W芯片的JTAG口用于GPIO

    使用过程中发现STM32W芯片在驱动液晶SPI液晶时,在调试状态下可以正常工作但在通常运行情况下却没有任何显示! 经查发现我使用的两个端口PC0和PC3的电平很不正常,拉不高. 所以我就怀疑到IO口问 ...

  8. SQLServer 分组查询相邻两条记录的时间差

    原文:SQLServer 分组查询相邻两条记录的时间差 首先,我们通过数据库中表的两条记录来引出问题,如下图 以上为一个记录操作记录的表数据.OrderID为自增长列,后面依次为操作类型,操作时间,操 ...

  9. Failed to issue method call: Unit mysql.service failed to load: No such file or directory解决的方式

    Failed to issue method call: Unit mysql.service failed to load: No such file or directory解决的方式 作者:ch ...

  10. Solr安装(Tomcat)

    Solr安装(Tomcat)   安装环境 Windows 7 64bit Apache-tomcat-8.0.9-windows-x64 Solr-4.9.0 JDK 1.8.0_05 64bit ...