代码签名证书是一种数字证书,它将经过验证的软件发布者与用于验证数字签名的公钥关联起来。发布者使用相应的私钥对软件进行签名。当该软件被下载或安装时,兼容系统可验证是谁签名的,并检测自签名以来被签内容是否发生了更改。

什么是代码签名证书?

代码签名证书是一种数字凭据,让软件发布者能够证明自身身份,并验证其代码在签名后未被修改。它将经过验证的发布者身份与用于创建和验证数字签名的密码学密钥关联起来。证书颁发机构(CA)会根据该证书的要求对申请者进行验证后签发证书。公钥包含在证书中,而相应的私钥则受到保护。这种分离是公钥基础设施(PKI)的基础:公钥可被分发用于签名验证,而无需向接收方提供用于创建签名的私钥。正因如此,仅靠代码签名证书本身无法对软件进行签名——签名需要访问与该证书中公钥相对应的私钥。在验证过程中,证书提供身份与公钥信息,用于评估对签名者的信任。

有效的代码签名有助于 Windows 识别软件发布者。若没有可识别的发布者身份,用户可能会看到"未知发布者"警告。

代码签名证书包含哪些信息?

代码签名证书包含将签名密钥与其发布者关联起来并评估证书信任所需的身份与公钥信息。作为 X.509 数字证书,它通常包含:主题信息——标识证书持有者或发布者;公钥——与签名时使用的私钥相对应;颁发者——标识签发该证书的证书颁发机构;有效期——指定证书的生效与失效时间;序列号——为颁发者唯一标识该证书;证书扩展——指定附加属性与允许用途,包括适用的代码签名用途;CA 签名——允许将证书认证为由该 CA 签发。

什么是代码签名?

代码签名是对软件应用密码学数字签名的过程,以便对发布者进行身份验证,并检测被签代码是否发生更改。它使用公钥密码学、数字证书与密码学哈希,在发布者与软件发布版本之间建立这种可验证的连接。

组件作用
代码签名对软件进行数字签名的过程
代码签名证书将经过验证的发布者身份与公钥关联
私钥创建发布者的数字签名
数字签名提供用于验证签名者并检测被签内容更改的密码学证据

这些组件共同构成"签名—验证"流程:发布者创建签名,接收方随后检查签名与已签内容。

代码签名如何工作?

代码签名利用公钥基础设施(PKI)与非对称密码学,对软件应用数字签名,使接收方能够验证是谁签名的,并检测被签内容是否发生变化。在签名过程中,会创建软件的密码学哈希,并使用发布者受保护的私钥对所得摘要进行签名。验证时则使用包含在代码签名证书中的相应公钥。

1. 发布者建立签名身份。对于公开信任的代码签名,发布者首先需要经过验证的证书,并访问相应的私钥,该私钥须使用经 FIPS 140-2 或公认等效标准验证的密码学硬件加以保护。签名身份与密钥设置就绪后,即可对软件进行签名。

2. 软件被哈希。当发布版本准备签名时,签名工具会对签名所覆盖范围的内容应用密码学哈希函数。结果是一个消息摘要——代表该内容的定长值。如果覆盖范围的内容在签名后发生更改,重新计算哈希会产生不同的摘要,从而使签名后的修改可被检测。

3. 私钥对摘要进行签名。使用发布者受保护的私钥,对摘要执行密码学签名操作,结果即与该软件关联的数字签名。常将其描述为"用私钥加密哈希",但该解释并不普遍适用于所有数字签名算法。更准确地说,私钥对摘要进行签名,而相应的公钥用于签名验证。

4. 签名与软件关联。数字签名以及验证所需的证书信息,随后会根据平台的签名格式被嵌入、附加或以其他方式与软件关联。具体结构因生态系统而异:某些格式将签名直接嵌入被签文件,而其他格式可使用单独签名的编录或特定于包的签名结构。

5. 添加可信时间戳。签名过程还可向可信时间戳服务请求时间戳。时间戳提供了签名在特定时刻存在的证据,日后有助于判断软件是否是在发布者证书有效期内签名的。

6. 接收方验证已签软件。当软件被检查时,验证方使用与签名证书关联的公钥验证数字签名,并检查被签内容是否仍产生预期的摘要。如果这些密码学检查成功,验证方即有证据表明签名是使用相应私钥创建的,且签名所覆盖的内容未作更改。证书信任、状态、时间戳及平台特定策略随后可分别评估。

代码签名有哪些好处?

代码签名的主要好处是发布者身份验证与软件完整性。代码签名证书有助于建立软件签名背后的身份,而数字签名则提供密码学证据,证明被签内容未作更改。身份——发布者身份验证:受信任的代码签名证书将经过验证的发布者身份与签名验证时使用的公钥关联起来。CA 在证书上的签名使验证方能够通过既定的证书链评估该身份。当软件签名与证书信任成功验证后,接收方即获得将已签软件与相应签名身份关联起来的密码学证据,该身份如何显示取决于操作系统或软件平台。完整性——软件完整性:数字签名提供证据表明签名所覆盖的内容在签名后保持完整。如果该内容被修改或损坏,密码学验证将不再与原始签名状态匹配,导致签名验证失败。因此,代码签名提供的是篡改证据,而非篡改预防——它无法阻止有人修改文件,而是能在验证签名时检测到被签内容的更改。

代码签名是否意味着软件是安全的?

并非如此。有效的代码签名并不能证明软件无恶意软件、无漏洞、无缺陷或在其他方面可安全运行。它确立的是关于签名者以及签名所覆盖内容是否更改的信息。合法的发布者可能无意中签署了存在漏洞的软件,而遭泄露的签名密钥也可能被滥用来签署恶意代码。因此,有效签名回答的是"谁签署了此文件?"与"被签内容是否更改?"——而非"此软件是否安全?"代码签名应与安全开发、测试、恶意软件检测、访问控制及其他软件供应链安全措施协同工作,而非取代它们。

代码签名证书与数字签名:有何区别?

代码签名证书是一种将经过验证的发布者身份与公钥关联起来的数字凭据,而数字签名是使用相应私钥对软件进行签名时创建的密码学证据。证书有助于确立谁控制签名身份;数字签名则允许验证签名者真实性与被签内容的完整性。

对比项代码签名证书数字签名
是什么将发布者与公钥关联的数字凭据签名过程中创建的密码学证据
由谁创建证书颁发机构使用发布者私钥的签名操作
关联对象发布者身份与公钥具体的已签软件/内容
主要作用支持对签名身份的验证支持对签名者真实性与内容完整性的验证
适用范围用于软件及其他支持代码签名的制品用于包括软件在内的众多数字签名场景
能否独立对软件签名否它是签名的结果,而非签名密钥

实践中,证书确立与签名密钥关联的身份,而数字签名提供与被签软件绑定的密码学证据。

当已签软件被验证时会发生什么?

当已签软件被验证时,系统会检查数字签名与被签内容,评估用于确立签名密钥信任的证书,并应用任何附加的平台特定策略。一个密码学上有效的签名,并不自动满足每一项信任或执行要求。

1. 密码学签名与完整性。验证方将密码学结果与根据已签软件计算出的摘要进行比对。如果被签内容已更改,数值不再对应,签名验证即告失败。成功的检查提供了证据表明被签内容自原始签名所覆盖的状态起未作更改。

2. 证书信任与状态。有效的密码学签名只是信任决策的一部分。验证方还会评估签名证书,以确立与签名密钥关联的身份,以及证书是否链接到受信任的根。它可能还会检查证书在相关签名时刻是否有效、是否允许代码签名,以及是否已被吊销或以其他方式失去信任。可信时间戳会影响签名证书过期后证书有效性的评估方式。

3. 平台特定策略。操作系统与软件生态系统可在密码学与证书检查之后施加附加要求,这些要求可能决定软件是被接受、警告、阻止还是进入其他平台特定流程。有效的签名并不自动意味着平台会允许该软件运行。

为何代码签名私钥需要强保护?

代码签名私钥需要强保护,因为任何未经授权获取它的人,都可能签署看似来自合法发布者的恶意或未授权软件。私钥代表着发布者的签名权限。与证书中的公钥不同,它必须免受未授权访问与使用。因此,遭泄露的签名密钥会破坏以该发布者身份发布的软件的信任。对于公开信任的代码签名证书,强密钥保护如今已是行业基线,而非仅 EV 才具备的特性。自 2023 年 6 月 1 日起生效的 CA/浏览器论坛要求规定,订户私钥必须在合适的硬件支持密码学保护内生成、存储与使用。根据签名模式的不同,这可以通过合规硬件、基于云的密钥保护或符合资格的签名服务来实现。

时间戳在代码签名中扮演什么角色?

代码签名中的时间戳,使数字签名即使在原始代码签名证书过期后仍可信且有效;它表明数字签名在特定时刻存在。没有可信时间戳,证书过期会使验证方更难确立签名是在证书有效期内创建的。有了被接受的时间戳,正确签名的软件在签名证书本身过期后,仍可依据平台验证规则继续通过验证。三个要素回答了不同的信任问题:证书确立签名身份;数字签名提供与被签内容绑定的证据;可信时间戳确立该签名存在的时间。

哪些类型的文件可以进行代码签名?

代码签名可用于多种类型的软件,包括可执行文件、库、安装程序、脚本、驱动程序与应用包。证书要求、签名格式与签名工具取决于被签平台与软件类型。

软件类型常见示例
可执行文件与库EXE、DLL
安装程序与包MSI、MSIX 及其他受支持的包格式
脚本PowerShell 及其他可签名的脚本格式
Java 应用/包JAR
Microsoft Office 代码VBA 项目与宏
驱动程序驱动程序包与已签编录文件
软件发布与更新平台支持的发布或更新包

这些制品并非都使用相同的签名格式或工具。Windows Authenticode、Java 签名、Office/VBA 签名、驱动程序签名及其他软件生态系统各有其要求。因此,发布者需要使用软件与目标平台所支持的签名方法。

是否存在不同类型的代码签名证书?

公开信任的代码签名证书根据验证级别分为两类:组织验证(OV)与扩展验证(EV)。OV 与 EV 证书都将经过验证的组织与签名身份关联起来,而 EV 涉及额外的验证要求。二者的区别主要在于验证,而非基础私钥保护是否重要。正确的验证级别取决于发布者的需求与目标环境。

常见问题

谁签发代码签名证书?公开信任的代码签名证书,由证书颁发机构(CA)根据适用的代码签名要求对申请者进行验证后签发。CA 签发一份将经过验证的发布者身份与签名验证时使用的公钥关联的证书。

谁需要代码签名证书?需要确立可验证的发布者身份、并允许接收方验证分发代码完整性的软件发布者,可能需要代码签名证书。常见用例包括 Windows 应用、安装程序、库、驱动程序、脚本、企业软件及其他可下载的软件制品。

一张代码签名证书能否签署多个应用?代码签名证书通常可用于签署同一经过验证的发布者发布的多个应用,前提是证书与签名设置满足这些应用与目标平台的要求。出于安全与运营原因,组织仍可在产品、团队或发布环境之间分离签名密钥或身份。

代码签名是否加密软件?代码签名并不加密软件或隐藏其内容。它创建的是一种数字签名,可允许验证签名者与被签内容的完整性。加密保护机密性,代码签名支持身份验证与完整性。二者使用相关的密码学技术,但解决的是不同的问题。