代码签名(英语:Code signing)是对可执行文件或脚本进行数字签名以确认软件作者及保证软件在签名后未被修改或损坏的措施。此措施使用加密散列来验证真实性和完整性。
定义代码签名(英语:Code signing)是对可执行文件或脚本进行数字签名以确认软件作者及保证软件在签名后未被修改或损坏的措施。此措施使用加密散列来验证真实性和完整性。1
代码签名可以提供几大功能价值。最常用的需求是代码签名为部署提供了安全性。在某些编程语言中,它也可用来帮助防止名字空间冲突。几乎每个代码签名的实现都提供某种数字签名机制来验证作者或构建系统的身份,以及校验对象是否未被修改。它也可用来提供对象相关的版本信息,以及存储对象的其他元数据。
代码签名作为软件安全性依赖的效果取决于所支持签名密钥的安全性。与其他公钥基础设施(PKI)技术一样,系统的完整性依赖于发布者对其私钥免受未经授权访问的保护。存储在通用计算机的软件中的密钥易于受到影响。因此,将密钥存储在安全、防篡改的硬件密码设备(也称硬件安全模块,HSM)是更加安全的最佳实践。
功能实现原理代码签名的基础是PKI安全体系。代码签名证书由签名证书私钥和公钥证书两部分组成。私钥用于代码的签名,公钥用于私钥签名的验证和证书持有者的身份识别。1
1. 发布者从CA机构(如VeriSign)申请数字证书;
2. 发布者开发出代码;借助代码签名工具,发布者将使用MD5或SHA算法产生代码的哈希值,然后用代码签名证书私钥对该哈希值签名,从而产生一个包含代码签名和软件发布者的签名证书的软件包;
3. 用户的运行环境访问到该软件包,并检验软件发布者的代码签名数字证书的有效性。由于VeriSign根证书的公钥已经嵌入到用户的运行环境的可信根证书库,所以运行环境可验证发布者代码签名数字证书的真实性;
4. 用户的运行环境使用代码签名数字证书中含有的公钥解密被签名的哈希值;
5. 用户的运行环境使用同样的算法新产生一个原代码的哈希值;
6. 用户的运行环境比较两个哈希值。如果相同,将发出通知声明代码已验证通过。所以用户可以相信该代码确实由证书拥有者发布,并且未经篡改。
整个过程对用户完全透明,用户将可以看到软件发布者提示信息,并可以选择是否信任该软件发布者。在选择信任软件发布者之后,运行所有该软件发布者签名的程序时将可以不再收到任何提示信息。
种类不同数字认证公司提供的代码签名分类不同,以下分类按照代码签名证书产品类型划分。
VeriSign 作为国际顶级的认证机构(CA),支持以下所有产品并且兼容性最好。其中微软徽标认证证书、微软移动代码签名证书、Brew代码签名证书是 VeriSign 专有的产品。其他代码签名证书产品则可以有更多的选择余地。
(1) 代码签名数字 ID(Code Signing Digital IDs): 主要包括:微软代码签名证书 (Microsoft Authenticode Digital ID) :数字签名 .exe, .dll, .cab, .msi, .ocx, .sys, .cat, .vbs;火狐控件(FireFox Extension)签名证书:数字签名 .xpi; Java 代码签名证书 (Sun Java Signing Digital ID) :数字签名 Sun J2SE/J2EE 的 Java Applet 文件,以及数字签名 J2ME MIDlet Suite 文件,支持业界最多型号和最多品牌的手机。 Office宏代码签名证书 (Microsoft® Office and VBA):数字签名 Office VBA 及宏代码;Adobe AIR代码签名证书 (Adobe® AIR);数字签名 .AIR 桌面应用程序;Shockwave代码签名证书 (Macromedia Shockwave®);数字签名使用Macromedia® Director® 8 Shockwave Studio创建的应用程序。
(2) 微软产品徽标认证证书 ("Designed for Windows logo" Digital IDs) :用于数字签名微软 Windows Logo 认证的各种软件、硬件驱动程序等,提交已经签名的软件给微软测试认证,还包括微软 Windows Hardware Quality Labs (WHQL) testing programs(Windows 硬件质量实验室测试计划 ) 认证。用户在向微软提交注册申请前,必须首先获取一张微软代码签名证书 (Microsoft Authenticode Digital ID)。在获取微软代码签名证书后,对微软Windows Logo 认证的各种软件、硬件驱动程序等进行数字签名,而后将已签名的软件给微软测试认证。从 Windows Vista开始,微软在x64位的系统上强制推行数字签名,没有经过WHDL和RDS认证并数字签名的硬件驱动程序将无法在Vista x64版本上成功安装。在后续的Vista版本上,微软会逐步加强对数字签名的要求,最终要求所有的应用程序必须经过签名才能在Windows系统上运行。对于开发过程中的项目,微软允许进行TestSign模式的签名。用户可以使用工具64Signer实现TestSign签名,避免把每一个开发中产生的临时版本的驱动文件都进行数字签名的麻烦。
(3) 微软移动代码签名证书 (Authenticated Content Signing for Microsoft Windows Mobile)(简称ACS,现已更名为Code Signing Account for Microsoft® Mobile2Market):支持使用微软 Windows Mobile 的 SmartPhone 和 Pocket PC 的移动终端操作系统的移动应用软件的非特权签名和特权签名,以确保移动下载的软件代码在移动终端 ( 如智能手机和 PDA) 的安全。
(4) Brew代码签名证书 (Authentic Document IDs for BREW) :用于数字签名高通公司推出的无线二进制运行开发操作环境下的 基于CDMA网络 "无线互联网发射平台" 上增值业务开发运行的 Brew 代码。支持高通公司 (Qualcomm)BREW 系统的 BREW 应用代码的数字签名,以确保 BREW 文件的安全应用。
(5) Symbian代码签名证书 (Symbian Siged) :用于数字签名 Symbian S60 操作系统的智能手机下的 sis、sisx 格式文件。
(6) Adobe PDF代码签名证书 (True Credentials® for Adobe) :用于数字签名 Adobe PDF 文档。
(7) Apple 代码签名证书
Code Signing Certificate for Apple
可以让软件开发商使用此签名证书在证书有效期内不限数量的对 Apple操作系统上运行的代码进行数字签名。
特点代码签名证书可消除 Internet Explorer 以及 Windows 操作系统中弹出的「不明发行商」。
完整的时间戳服务包括免费的在你的代码上盖上时间戳以保证签名不会过期。每月签名次数不超过50次。 可以随时进行证书更换。
短时间之内快速反馈。
自证书审核完毕之日起,7 天内无条件退款。
一般都会有风险担保。
完善的在线服务电话和电子邮件技术支持。
免费证书安装状态检查。
安全保证许多代码签名的实现提供方法来使用涉及一组密钥的系统来签名代码,这类似SSL与SSH的流程。例如,在.NET中,开发人员每次构建之时,都将使用一个私钥来签名自己的库或可执行文件。此密钥唯一且分属给单个开发人员、小组,或者特定应用程序或实体。开发人员可以自己生成此密钥,也可以从受信任的数字证书认证机构(CA)获取一份密钥。2
代码签名在分发目的下很有价值,因为所提供代码的源代码可能并不明显,如Java applet、ActiveX控件或其他类似代码。它的另一个重要用途是,为现有软件安全地提供更新和补丁。Windows、Mac OS X和大多数Linux发行版为更新使用代码签名,从而确保其他人不可能通过补丁系统分发恶意代码。它可以使操作系统验证更新是否合法,即使更新是由第三方或借助物理介质(如光盘、U盘)分发。
在Windows和Mac OS X上,首次运行软件时将检查代码签名以验证软件的身份,确保软件没有被第三方分销商或下载网站恶意篡改。因为平台的分散性,这种代码签名形式没有在Linux上使用,软件包管理系统是所有软件形式(不仅仅更新和补丁)的主要发行模式,并且允许直接检查源代码的开放源代码模型(如果需要)。
使用证书颁发机构用于代码签名的公钥应该可以追溯到受信任的根机构CA,使用安全的公钥基础设施(PKI)是最佳做法。这虽不能保证代码本身的可信,但可以确保它来自所声明的来源(更明确来说,来自特定私钥)。一个CA提供者可以提供根级别的信任,并能以代理方式将信任分配给其他人。如果用户信任一个CA,那么用户也相信该CA及其代理生成的密钥所签名的代码合法性。许多操作系统和框架都内置对一个或多个现有CA的信任(例如VeriSign/Symantec、DigiCert、TC TrustCenter、Comodo、GoDaddy及GlobalSign等)。对大型组织来说,实现与公共CA功能相同但仅在组织内信任的私有CA也是常见的选择。
CA的替代品类似目的的另一种方式是——开发人员可以使用自己生成的密钥。在此种情况下,用户首次通常必须直接从开发人员那里获取公钥,以便验证对象的来源。许多代码签名系统将存储签名中的公钥。部分软件框架和操作系统将在执行前检查代码的签名,并允许用户选择是否信任该开发者。应用程序开发者可以在安装程序中包含公钥以提供类似的系统。然后可以使用密钥来确保需要运行的任何后续对象(例如升级、插件或其他应用程序)都是来自同一开发人员。
时间戳时间戳旨在解决证书过期后开始出现的信任警告。在实际应用中,时间戳将使代码的信任期延长到证书有效期之后。
如果由于鉴权泄露或失效而必须撤销证书,则撤销事件的具体时间将纳入撤销记录。在这种情况下,时间戳有助于确认代码是在证书信任受损之前还是之后签署。
问题同任何安全措施一样,代码签名也可以被击破。用户可能被诱骗而运行无签名乃至拒绝被验证的代码,并且系统只能尽可能保持私钥的安全性。
同样重要的是,代码签名不会保护最终用户免受软件作者的恶意行为或无意破坏,而只是确认软件未被作者以外的人修改。
未签名代码在诸如游戏主机等消费者设备语境中,未签名代码通常指一个未被通常必须有加密密钥的应用程序接受和执行的软件。大多数主机游戏必须使用主机制造商设计的私钥签名,否则游戏不会在主机上加载。使未签名代码被执行通常有几种方法,包括软件漏洞、使用modchip、运用交换技巧技术,或者运行一个softmod。
对于有签名的应用程序复制到另一张DVD上就不能启动的原因,通常不那么显而易见。在Xbox上,原因是Xbox可执行文件(XBE)包含一个媒体类型标志,它指定了XBE可引导形式的媒体类型。对几乎所有Xbox软件来说,此设置使得可执行文件只能从工厂生产的光盘启动,将可执行文件复制到可烧录媒体上将终止软件的可执行性。
但是,因为可执行文件本已签名,因此仅更改标记值不可行,那将使可执行文件的签名失效,从而在最初的验证阶段就检查失败。
展望伴随着物联网(IoT)增长的互联设备正成为代码签名的新需求。随着越来越多的传感器和设备被接入紧密的网络生态系统,证书颁发机制已被扩展到人员识别以外的机器识别。与代码签名一样,该技术使用数字证明确保了代码的物理真实性和完整性,及在产品生命周期内随时进行代码的验证与升级。这正为代码签名创造新的纬度:提高安全意识,以及需要在专用的保护环境中保存私有签名密钥,为整个系统创建信任的根源。鉴于恶意软件和高级持久威胁(APT)的流行,许多软件供应商、在线服务提供商、企业IT组织和高科技IoT设备的制造商都面临着增加其高科技制造和代码签名过程安全性的压力。
本词条内容贡献者为:
王沛 - 副教授、副研究员 - 中国科学院工程热物理研究所