运行 Windows Vista 的系统上内核模块的数字签名
Microsoft Corporation
更新时间:2007 年 6 月
适用于:
Windows Vista
Windows Server 2008
摘要: 对于 Microsoft windows Vista 和更高版本的 Windows 操作系统系列,内核模式软件必须具有数字签名才能在基于 x64 的计算机系统上加载。 了解如何管理 Windows Vista 内核模式软件的签名过程。 (22 页打印页)。
本文的当前版本在 Web 上维护:https://www.microsoft.com/whdc/system/platform/64bit/kmsigning.mspx。
内容
介绍
数字签名作为最佳做法
内核模式代码签名选项
内核模式代码签名过程
如何获取软件发布证书(SPC)
创建已签名的 .cat 文件
将嵌入签名添加到驱动程序映像文件
如何在开发过程中禁用签名强制
如何使用测试签名
启用测试签名故障排除
检测驱动程序加载错误
启用代码完整性诊断系统日志事件
驱动程序验证调试选项
资源
介绍
对于世界各地的 Windows 消费者和企业用户来说,保护个人和企业数据仍然是首要问题。 Microsoft致力于实施新的方法来帮助限制恶意软件的传播。 内核模式软件的数字签名是确保计算机系统上安全性的重要方法。
数字签名允许安装基于 Windows 的软件的管理员或最终用户知道合法发布者是否提供了软件包。 当用户选择在发生错误或其他错误后将 Windows 错误报告数据发送到Microsoft时,Microsoft可以分析数据,以了解错误时系统上运行的发布者软件。 然后,软件发布者可以使用Microsoft提供的信息查找和修复软件中的问题。
Windows Vista 依赖于内核模式代码上的数字签名来提高 Microsoft Windows 平台的安全性和稳定性,并通过下一代高级内容启用新的客户体验:
- 必须为流式传输受保护内容的设备对驱动程序进行签名。 这包括使用受保护的用户模式音频(PUMA)和受保护的音频路径(PAP)的音频驱动程序,以及处理受保护视频路径输出保护管理(PVP-OPM)命令的视频设备驱动程序。
- 未签名的内核模式软件不会加载,也不会在基于 x64 的系统上运行。
注意: 即使是具有管理员权限的用户也不能在基于 x64 的系统上加载未签名的内核模式代码。 这适用于在内核模式下加载的任何软件模块,包括设备驱动程序、筛选器驱动程序和内核服务。
新的内核模式代码签名策略的范围非常广泛。 对于发布内核模式软件的开发人员,此策略具有以下效果:
对于尚未签名的任何内核模式组件,发布者必须获取软件发布证书(SPC),并使用 SPC 对将在运行 Windows Vista 的基于 x64 的计算机系统上运行的所有 64 位内核模式软件进行签名。 这包括内核模式服务软件。
提供 64 位设备驱动程序或其他已通过 Windows 徽标计划签名的内核模式软件的发布者将具有使用 Windows 硬件质量实验室(WHQL)签名签名的驱动程序目录。 若要在提交到 WHQL 之前完全测试驱动程序包,请使用 SPC 对驱动程序目录进行签名。
在启动驱动程序的特殊情况下,还需要使用 SPC 对驱动程序二进制映像文件进行嵌入签名,以获得最佳的系统启动性能。
注意 Windows Vista 操作系统加载程序加载驱动程序时,将启动驱动程序。 启动启动驱动程序可以按如下方式标识:驱动程序 INF 将启动类型指定为“Start=0”,或者将 ServiceType 配置为内核驱动程序或文件系统驱动程序和 StartMode 配置为“boot”。
必需的内核模式代码签名策略适用于运行 Windows Vista 的基于 x64 的系统上的所有内核模式软件。 但是,Microsoft鼓励发布者对所有软件进行数字签名,包括 32 位和 64 位平台的设备驱动程序。 Windows Vista 在 x86 系统上执行内核模式签名验证,以支持受保护的媒体内容。 但是,32 位系统不需要内核模式驱动程序签名。
本文介绍如何管理 Windows Vista 内核模式代码的签名过程,包括如何获取软件发布证书(SPC)、保护密钥指南,以及如何使用 Windows 驱动程序工具包(WDK)中提供的工具对驱动程序包进行签名。
数字签名作为最佳做法
自 Windows 98 发布以来,Microsoft已将指定设备类的驱动程序签名提升为提高驱动程序可靠性的机制,以提供更好的用户体验,降低软件和硬件供应商的支持成本,并降低客户总拥有成本。
对于设备驱动程序和其他内核模式软件,作为 Windows 徽标计划的一部分签名的驱动程序会增加最终用户对软件质量的信心并提高用户体验,因为属于驱动程序的 Windows 徽标表示驱动程序已经过测试,并且 Windows 徽标附带的数字签名自测试以来尚未更改。
对于大多数内核模式驱动程序包,数字签名在已签名的目录 (.cat) 文件中提供。 Windows 硬件质量实验室(WHQL)提供了一个Microsoft签名的 .cat 文件,用于分发符合 Windows 徽标程序要求的驱动程序包。
创建签名内核模式软件的过程包括两个不同的但相关的活动。 这些操作可以并行完成,因为软件通常不必签名,直到开发过程相对较晚。
管理签名过程。 这通常由发布者的计划管理和软件发布服务处理,包括:
- 选择适当的签名选项。
- 获取所需的证书。
- 管理数字签名或代码签名密钥。
注意 若要对图像二进制文件或目录进行数字签名,软件发布者必须具有经过认证的代码签名密钥,这意味着证书颁发机构已足够建立发布者的标识。
实现要签名的驱动程序。 这通常由发布者的开发团队处理,包括:
- 实现驱动程序本身。
- 创建用于内部测试或发布的已签名驱动程序包。
这些过程记录了 WDK 和平台 SDK 中早期版本的 Windows。 本文介绍与 Windows Vista 的内核模式代码签名相关的其他选项。
内核模式代码签名选项
有多种选项可用于在 Windows Vista 中使用内核模式代码签名(KMCS)要求。 Windows Vista 在开发内核模式代码时,无需对驱动程序文件进行签名。 相反,开发人员可以使用其中一种机制在开发和非自动化测试系统上暂时禁用内核的负载时间检查。 但是,需要测试驱动程序包的测试签名才能在测试系统上自动安装驱动程序包,而无需安装驱动程序弹出窗口。 驱动程序管理基础结构(DMI)在安装过程中验证驱动程序包签名,并警告用户未签名的驱动程序。
下表比较了 Windows Vista 支持的数字签名内核模块的选项。
用于 签名内核模块的
签名选项 | 已验证以满足徽标要求的功能 | 标识已验证 | 预期用途 |
---|---|---|---|
Windows 徽标程序 | 是的 | 是的 | 释放 |
使用 SPC 进行内核模式代码签名 | 不 | 是的 | 释放 |
WHQL 测试签名程序 | 不 | 是的 | 测试 |
KMCS 测试签名 | 不 | 不 | 测试 |
Windows 徽标程序验证正确的驱动程序功能并确保高质量和可靠性。 提交到 Windows 徽标计划的驱动程序包由Microsoft进行数字签名。 Windows 徽标程序接受通过 INF 文件安装的符合 Windows 徽标要求的硬件的设备包。 驱动程序发布者在完成 Windows 徽标计划的驱动程序验证测试后提交驱动程序包。 符合徽标资格的驱动程序会收到Microsoft签名的 .cat 文件。 有关 Windows 徽标计划的信息,请参阅本文末尾的“资源”部分。
开发人员可以使用 SPC 对驱动程序映像文件或驱动程序目录进行签名,以便在提交到 WHQL 之前进行测试,以验证驱动程序是否加载并正常运行。
使用 SPC 进行内核模式代码签名可提供内核模块加载到 Windows Vista 中的发布者的可识别性。 它不提供任何级别的功能认证或内核模块的可靠性。 对于不符合 Windows 徽标条件的驱动程序,或者 Windows 徽标不是产品要求之一,发布者可以为驱动程序包创建 .cat 文件,并使用发布者的 SPC 对其进行签名。
内核模式代码签名的重要 不会替换 WHQL 程序。 Microsoft鼓励发布者使用 Windows 徽标计划来确保驱动程序质量。 内核模式代码签名不需要软件发布者通过与 WHQL 关联的 Windows 徽标程序测试要求。
签名的 .cat 文件是大多数驱动程序包在 x64 系统上正确安装和加载所必需的,但包含由 Windows Vista 启动加载程序加载的驱动程序的包除外。 包含 Windows Vista 启动加载程序加载的设备驱动程序的驱动程序包必须采用两种方式进行签名:
- 在启动时加载的内核模式驱动程序二进制文件必须在使用 SPC 签名的二进制文件中具有嵌入签名。 为简单起见,可以更轻松地对包中的所有驱动程序映像文件进行嵌入签名。
- 使用 INF 文件安装的驱动程序包还必须具有已签名的目录文件,就像不包含启动启动驱动程序的驱动程序包一样,以便在安装过程中进行签名验证。
制造商应确保硬件供应商获取 SPC,并签署将在制造商安装的系统上安装的任何启动驱动程序。
为了在开发周期内进行测试,建议使用“测试”证书进行代码签名,而不是使用发布证书进行签名。 仅当启用了允许使用测试签名证书的启动配置选项时,Windows Vista 系统才会识别测试签名二进制文件。 默认情况下未启用测试签名,大多数 Windows Vista 系统都不会信任测试签名。
测试签名还支持 WHQL 测试签名计划。 程序中的参与者可以提交 WHQL 测试签名的驱动程序包。 测试签名目录上的签名由Microsoft测试根机构下颁发的证书生成。 当 Windows Vista 启动配置设置启用测试签名时,将接受Microsoft测试根机构。 有关 WHQL 测试签名计划的信息,请参阅本文末尾的“资源”部分。
对于“测试”和“发布”签名,开发团队应遵循密钥管理的最佳做法,如本文后面的保护代码签名密钥指南中所述。
本文档后面的“如何使用测试签名”部分中更详细地讨论了测试签名。
内核模式代码签名过程
对内核模式映像文件或目录进行数字签名可建立已签名文件或文件的完整性。 执行代码签名操作后,不应修改软件模块。 代码签名后修改映像文件会导致安装时间和加载时间签名验证失败。
可以使用目录对包含多个文件的驱动程序包进行签名。 驱动程序包必须具有已签名的目录 (.cat) 文件,该文件用于在安装驱动程序包时标识发布服务器,并在驱动程序映像加载到内核时验证驱动程序映像。 目录文件包含一个数字证书,用于标识发布者,以及允许系统验证包中文件尚未更改的包内容的哈希。
如前所述,启动启动驱动程序必须在驱动程序映像文件中具有嵌入式签名。 启动启动驱动程序映像文件中的嵌入式签名可优化操作系统启动性能,无需在操作系统加载程序验证驱动程序签名时找到 appropriate.cat 文件。
驱动程序开发过程中每个生成都不需要驱动程序签名。 开发人员可以禁用驱动程序签名强制,如本文后面的“如何禁用签名强制实施”中所述。
以下部分讨论如何获取和管理证书。 本文稍后将讨论签名驱动程序包的机制。
如何获取软件发布证书(SPC)
使用以下步骤获取用于对内核模式软件进行签名的 SPC,该软件符合必需的内核模式代码签名策略:
- 从颁发用于签名内核模式代码的数字证书的商业 CA 获取 SPC。 提供可用于内核模式代码签名的软件发布证书(或代码签名证书)的 CA 列表可在 Windows Vista 内核模式代码签名 网页的
Microsoft跨证书。 - 从颁发 SPC 的根证书颁发机构的 windows Vista 内核模式代码签名 网页的
Microsoft跨证书下载相应的跨证书。 跨证书用于内核模式代码的数字签名中,以便可将签名验证为 Windows Vista 内核已知的受信任根机构。
从商业 CA 请求软件发布证书时,请按照 CA 网站上的说明操作,了解如何在将使用私钥对代码进行签名的计算机上获取和安装代码签名证书。
有关保护代码签名密钥的指导
代码签名过程的核心加密密钥必须受到很好的保护,并受到与任何公司最有价值的资产相同的处理。 这些密钥表示公司标识。 使用这些密钥签名的任何代码都会出现在 Windows 上,就好像它包含可跟踪到公司的有效数字签名一样。 如果密钥被盗,则它们可用于欺诈性地对恶意代码进行签名,并可能导致交付包含似乎来自合法发布者的特洛伊木马或病毒的代码。
有关安全保护私钥的详细信息,请参阅 代码签名最佳做法。
将跨证书与内核模式代码签名配合使用
内核模式代码签名使用跨证书作为代码签名过程的一部分。 跨证书是由一个证书颁发机构(CA)颁发的 X.509 证书,用于为另一个证书颁发机构的根证书签名公钥。 Windows Vista 操作系统加载程序和内核在验证驱动程序签名时识别跨证书。 跨证书允许内核具有单个受信任的Microsoft根颁发机构,但也提供了将信任链扩展到颁发软件发布者证书的多个商业 CA 的灵活性。
跨证书使开发人员和发布者能够使用软件发布者证书对内核模式软件进行签名。 使用内核模式代码签名的开发人员会将正确的跨证书(.cer)文件下载到执行数字签名操作的系统。 发布者不需要使用其软件或驱动程序包分发跨证书文件。 交叉证书将包含在驱动程序映像文件或驱动程序包目录中的数字签名中。 安装驱动程序包的用户无需执行 Windows Vista 的任何配置步骤即可验证包含跨证书的数字签名。
重要 Windows Vista Beta2 WDK 中的 SignTool 是唯一支持将跨证书添加到数字签名的 SignTool 版本。 Windows Server 2003 平台 SDK 或 DDK 中的早期版本的 SignTool 不支持添加跨证书。
可从 Microsoft WHDC 网站下载用于内核模式代码签名的多个 CA 的跨证书。 有关详细信息,请参阅本文末尾的资源中 Microsoft Windows Vista 内核模式代码签名 的跨证书。
有关如何将跨证书添加到数字签名的详细信息,请参阅有关如何对 .cat 文件进行签名以及向驱动程序映像文件添加嵌入式签名的部分。
生成测试证书
测试证书用于代替 SPC 来测试签名内核模式软件模块,这些模块不适用于组织外部的分发或发布。 测试签名将数字签名应用于内核模式二进制文件或驱动程序包目录,用于内部测试。 本文档后面的“如何使用测试签名”部分中更详细地讨论了测试签名。 将测试证书用于内核模式代码签名时,不需要交叉证书。
可以使用企业 CA 或使用 Makecert 实用工具生成测试证书。 有关在组织中使用企业 CA 颁发测试签名证书的详细信息,请参阅 代码签名最佳做法。
在以下示例中,Makecert 生成由默认测试根颁发的测试证书,将私钥存储在密钥容器中,并将证书输出到证书存储和证书文件:
Makecert –r –pe –ss SubjectCertStoreName –n "CN= CertName" OutputFile.cer
示例中用于 Makecert 的参数执行以下操作:
-
-r
创建自签名证书,即证书是根证书。 -
-pe
使与证书可导出关联的私钥。 -
-ssSubjectCertStoreName
指定包含根证书的证书存储的名称。 - **-n “CN=**CertName”
指定证书的名称。 如果未提供证书名称,则证书的默认名称为“Joe 的软件 Emporium”。 -
OutputFile.cer
保存根证书的文件的名称。
WDK 中提供了使用 makecert 的示例命令脚本。 脚本文件名位于“bin\selfsign”目录下,selfsign_example.txt。 在安装驱动程序包之前,必须将测试证书添加到目标测试计算机上的证书存储中。
以下示例演示如何将测试证书添加到目标测试计算机上的受信任根存储和受信任的发布服务器存储。
certmgr.exe -add OutputFile.cer -s -r localMachine root
certmgr.exe -add OutputFile.cer -s -r localMachine trustedpublisher
示例中 Certmgr 的参数执行以下操作:
-
-add
将证书文件中的证书添加到证书存储中。 -
-s
指示证书存储是系统存储。 -
-r
指示系统存储的注册表位置位于HKEY_LOCAL_MACHINE键下 -
根 或 trustedpublisher
指示系统证书存储的名称
有关 Certmgr 和 Makecert 的详细信息,请参阅本文末尾的资源。
创建已签名的 .cat 文件
用于生成和签名目录文件 MakeCat 和 SignTool 的工具在 Windows Vista WDK 中提供。
注释 Signtool.exe 和 MakeCat.exe 位于 WDK 的“bin\selfsign”目录中。
如何创建 .cat 文件
数字签名的 .cat 文件包含加载到内核时验证的所有内核模式模块的哈希。 目录文件还可以包括软件包中的其他文件的哈希,例如用户模式应用程序程序(.exes)和应用程序扩展(.dlls)。 Microsoft建议 .cat 文件包含软件包中所有文件的哈希。
.cat 文件包含对应于指定文件集的文件哈希列表。 文件哈希是基于目标文件的 SHA1 哈希的乘积。 平面文件哈希不用于使用可移植可执行文件(PE)文件格式的文件(如驱动程序)。 相反,相关部分(如 PE 标头、可执行数据和经过身份验证的属性)会选择性地进行哈希处理。
将驱动程序加载到内存中时,Windows Vista 内核对驱动程序二进制映像文件的相关部分执行 SHA1 哈希。 Windows 通过将生成的哈希值与关联的 .cat 文件中的二进制哈希列表进行比较来验证该文件是否未被篡改。
如果通过即插即用安装驱动程序,请使用 WDK 中的可签名工具创建目录,如下所示。 否则,请根据本文后面的“如何手动创建目录”中所述手动创建目录。
如何使用可签名性创建目录
可签名性是用于验证 INF 文件并根据 INF 文件创建目录文件的工具。 它包含在 WDK 中,可以从 WDK 生成环境运行。 可签名性需要驱动程序包的有效 INF 文件。 有关创建 INF 文件的信息,请参阅 WDK 文档。 若要使用可签名工具创建目录,请按如下所示:
使用可签名创建目录
- 创建一个驱动程序包目录,其中包含驱动程序包中的所有文件。
- 在驱动程序包目录中创建 INF 文件,并为 Windows Vista 编辑该文件。 具体而言,将生成日期更改为 2006 年 4 月 1 日或更高版本,并将版本更改为 6。 例如:DriverVer=2006/04/01、6.0.1.0
- 运行可登录性以基于 INF 文件创建有效的 .cat 文件:
运行 Signability.exe 并使用 GUI 创建目录文件。
从命令行运行可签名性。 请注意,package_directory 必须是包目录的完全限定路径。
Signability.exe /auto /cat /driver:package_directory /os:512
此示例使用可签名性支持的多个参数在 driver_package 目录中创建 .cat 文件:
-
/auto
将可签名性工具配置为无需用户交互即可运行。 -
/cat
配置可签名工具以生成由驱动程序包 INF 文件提供其名称的目录文件。 -
/driver:DriverPath
提供包含驱动程序包文件的目录的路径。 -
/os:nnn
配置可签名工具,以验证驱动程序包 INF 文件是否符合标志值 nnn指定的 Windows 版本的要求。 512 是 Windows Vista(64 位版本)的值。
如何手动创建目录
若要手动创建 .cat 文件,请先使用文本编辑器创建目录定义文件(.cdf)。 .cdf 文件包括要编录的文件及其属性的列表。
以下示例显示了名为 Good.cdf的典型 .cdf 文件的内容。 要编录的包包含两个文件:File1 和 File2。 生成的 .cat 文件命名为 Good.cat。
[CatalogHeader]
Name=Good.cat
PublicVersion=0x0000001
EncodingType=0x00010001
CATATTR1=0x10010001:OSAttr:2:6.0
[CatalogFiles]
<hash>File1=File1
<hash>File2=File2
.cat 文件是使用命令行工具 MakeCat 创建的,该工具包含在平台 SDK 和 WDK 中。 MakeCat 工具:
- 验证每个列出的文件的属性列表。
- 将列出的属性添加到 .cat 文件。
- 对列出的每个文件进行哈希处理。
- 将每个文件的哈希存储到 .cat 文件中。
创建 .cat 文件
- 使用文本编辑器创建一个 .cdf 文件,其中包含要编录的文件列表及其属性。
- 针对 .cdf 文件运行 MakeCat。
Note MakeCat 不会修改 .cdf 文件。
以下示例演示如何从 Good.cdf 生成 .cat 文件。 -v 标志指定 MakeCat 的详细版本。 哈希文件和新生成的 Good.cat 文件放置在 File1 和 File2 所在的同一文件夹中。
MakeCat -v Good.cdf
.cat 文件现已准备好签名。
有关 MakeCat 和 .cdf 文件格式的详细信息,请参阅本文末尾的资源中列出的 MakeCat 文档。
如何对 .cat 文件进行签名
MakeCat 生成的 .cat 文件包含在用户系统上安装内核模式模块所需的所有文件哈希。 但是,还必须对文件进行数字签名。
.cat 文件使用命令行工具 SignTool 进行签名。 目录中用于验证内核模式映像文件的数字签名必须包含跨证书。 使用 SignTool 的新命令选项添加跨证书。
重要 必须使用 Windows Vista Beta2 WDK 中的 SignTool 版本将跨证书添加到数字签名。
以下示例演示如何使用 Signtool 通过 SPC 和导入到 Windows 证书存储中的相应私钥对 .cat 文件进行签名。 有关如何将 Signtool 与 HSM 配合使用的信息,请参阅本文末尾的 Resources 中列出的 SignTool 文档。
SignTool sign /v /ac CrossCertificateFile /s SPCCertificateStore /n SPCSubjectName /t http://timestamp.verisign.com/scripts/timestamp.dll Good.cat
此示例使用 SignTool 支持的多个参数:
-
签名
配置该工具以对名为 CatFileName.cat 的 .cat 文件进行签名。 -
/v
指定成功执行和警告消息的详细选项*.* -
/ac
将跨证书从文件 CrossCertificateFile 添加到数字签名 -
/s
指定 SPCCertificateStore 命名的证书存储。 -
/n
指定使用者名称 SPCSubjectName 的证书。 -
/tURL
指定数字签名将由 URL 指示的时间戳颁发机构(TSA)时间戳。
重要 目录或驱动程序签名雾包含时间戳,以便在签名者的代码签名私钥遭到入侵时提供密钥吊销所需的信息。
在设备安装期间,如果用于签名的 SPC 已过期且签名未加时间戳,则不会安装 .cat 文件,并且 Windows 不允许加载驱动程序。 但是,如果签名由受信任的时间戳颁发机构时间戳,则会安装 .cat 文件,Windows 允许加载驱动程序。
对自解压缩下载文件进行签名
在产品支持网站上发布用于分发的软件通常打包在自解压缩存档文件中。 使用 Web 浏览器下载自提取可执行文件,并在用户开始在其计算机上安装之前提取的内容。 使用对驱动程序包 .cat 文件进行签名的 SPC 还可以对自解压缩 .exe 文件进行数字签名。
对自提取 .exe 文件进行数字签名可标识存档文件的发布者,并确保通过 Internet 下载的自解压缩 .exe 文件的完整性。 下载自提取 .exe 文件的用户通常会在选择下载并运行自解压缩文件时收到信任对话框或安全警告。
在 Windows Vista 中,如果用户查看“安全警告”对话框的详细信息并选择“始终从 <发布者名称>安装软件”,则此选项将简化安装驱动程序包时的后续确认。 安装驱动程序包后,系统会询问用户是否信任已签名驱动程序包的发布者,然后驱动程序安装开始。 如果用户在下载自解压缩 .exe 文件时始终从驱动程序发布者中选择了安装软件的选项,则不会在驱动程序安装过程中出现信任对话框提示。
如何安装已签名的 .cat 文件
对于通过即插即用安装的驱动程序,安装过程中不会发生任何更改。 在标准 INF 和安装机制之外,安装嵌入式签名驱动程序不需要特殊处理。 请注意,仅允许属于管理员组成员的用户安装驱动程序包。
未通过即插即用安装的驱动程序必须在系统目录根文件夹中安装其 .cat 文件。 可以使用现有的 Win32 目录 API 调用来管理目录根文件夹中的目录安装,具体 CryptCATAdminAddCatalog。
将嵌入签名添加到驱动程序映像文件
若要在启动时优化驱动程序验证的性能,除了包的已签名 .cat 文件之外,启动驱动程序二进制文件还必须使用 SPC 具有嵌入式签名。 嵌入式签名可在操作系统启动期间节省大量时间,因为无需操作系统加载程序在驱动程序中查找 .cat 文件。 典型的 Windows Vista 系统在目录根存储中可能有一百多个不同的目录文件。 查找正确的目录文件以验证特定驱动程序的图像哈希可能涉及大量系统开销,搜索多个目录以查找正确的文件。
启动驱动程序是根据服务 StartType 值SERVICE_BOOT_START (0) 标识的。
嵌入签名不会干扰 .cat 文件签名或验证。 请注意,目录和嵌入签名中包含的哈希有选择性地排除 PE 文件格式的签名部分
若要使用 Signtool.exe 使用 SPC 和导入到 Windows 证书存储中的相应私钥将签名嵌入启动驱动程序二进制文件,请使用以下命令:
SignTool sign /v /ac CrossCertificateFile /s SPCCertificateStore /n SPCSubjectName /t http://timestamp.verisign.com/scripts/timestamp.dll winloaddriver.sys
此示例使用 SignTool 支持的多个参数:
-
签名
签名 命令将工具配置为对名为 winloaddriver.sys的驱动程序进行签名。 -
/v
指定成功执行和警告消息的详细选项*.* -
/ac
将跨证书从文件 CrossCertificateFile 添加到数字签名 -
/s 选项
指定名为 SPCCertificateStore 的证书存储 -
/n
指定使用者名称 SPCSubjectName的证书。 -
/tURL
指定数字签名应由 URL 指示的 TSA 时间戳。
重要提示: 目录或驱动程序必须加时间戳,因为这样将为密钥吊销提供必要的信息,以防签名者密钥遭到入侵。
如何验证嵌入签名
以下过程演示如何使用 Windows 资源管理器验证嵌入的签名。
验证嵌入签名
- 运行 Windows Vista 时,右键单击驱动程序 .sys 文件,然后单击上下文菜单中 属性。
- 单击 数字签名 选项卡(如果存在)。
- 如果此选项卡不存在,则该文件没有嵌入的签名。
- 选择签名者并单击 详细信息 打开 签名详细信息 对话框。
- 单击 查看证书 打开证书的属性页。
- 验证是否没有警告对话框。
- 验证证书使用者名称是否 发布服务器注册到已识别的证书颁发机构。
- 单击“认证路径” 选项卡。
- 验证顶部证书的使用者名称是否 Microsoft代码验证根。
使用内核模式代码签名策略的 signtool.exe 验证嵌入签名
- Signtool.exe 可用于使用以下命令验证 .cat 文件中的签名:
Signtool verify /kp /c tstamd64.cat toaster.sys
验证文件 toaster.sys 的图像哈希是否在目录文件中找到。 该工具返回字符串“Success”。
如何在开发过程中禁用签名强制
在开发的早期阶段,开发人员可以在 Windows 中禁用强制实施,以便不需要驱动程序签名。 以下选项可供开发人员暂时禁用内核模式代码签名强制,以便 Windows Vista 加载未签名的驱动程序。
附加内核调试器。 将活动内核调试器附加到目标计算机会禁用 Windows Vista 中内核模式签名的强制实施,并允许驱动程序加载。
使用 F8 选项。 Windows Vista 中引入的 F8 高级启动选项(“禁用驱动程序签名强制”)仅适用于当前启动会话禁用内核签名强制。 此设置不会在启动会话之间保留。
设置启动配置。 Windows Vista Beta2 版本中提供了启动配置设置,可禁用在启动会话中保留内核模式签名的强制实施。
Windows Vista 包括命令行工具 BCDedit,可用于在 Windows Vista Beta2 中设置选项以禁用签名检查。 若要使用 BCDedit,用户必须是系统上的 Administrators 组的成员,并从提升的命令提示符运行该命令。 可以通过创建桌面快捷方式来启动提升的命令提示符,以 cmd.exe,然后使用右键单击并“以管理员身份运行”。
下面显示了在命令提示符处运行 BDCedit 的示例:
// Disable enforcement – no signing checks Bcdedit.exe –set nointegritychecks ON // Enable enforcement – signing checks apply Bcdedit.exe –set nointegritychecks OFF // Disabling integrity check on an alternate OS // specified by a GUID for the system ID Bcdedit.exe –set {4518fd64-05f1-11da-b13e-00306e386aee} nointegritychecks ON
注意 禁用完整性检查的 Bcdedit 选项仅适用于在 Windows Vista Beta2 版本中加载未签名的驱动程序。 有关详细信息,请参阅 MSDN 网站上的 BCD 编辑器常见问题解答。
如何使用测试签名
测试签名为开发组织提供了其他选项,用于为尚未准备好发布的预发布软件合并内核模式代码签名。 测试签名允许使用“测试”代码签名证书对 Windows Vista 上加载的驱动程序进行签名,当 Windows Vista 启动配置设置允许测试签名时,这些驱动程序将加载。
测试签名可能适用于以下方案:
- 开发团队需要在测试系统上测试驱动程序的预发行版本,因为附加内核调试器并不实用。
- 内核模式软件的自动测试使得使用 F8 高级启动选项在每台计算机启动周期中暂时禁用驱动程序签名强制是不切实际的。
测试签名允许开发人员以 Windows Vista 验证和加载已签名驱动程序的方式对内核模式二进制文件的预发行版本进行签名。 测试签名涉及与正常生产或发布签名的以下差异:
- 可以使用 Makecert.exe 代码签名工具生成用于测试签名的证书,也可以由企业 CA 颁发,而不是使用商业 CA 颁发的 SPC。
- 必须在将加载测试签名驱动程序的 Windows Vista 系统上启用启用测试签名的 Windows Vista 启动配置选项。
开发组织可以设置企业 PKI 并颁发自己的测试代码签名证书以用于测试签名。 当 Windows Vista 启用测试签名时,驱动程序二进制文件上的数字签名验证将接受由 任何 CA 或颁发机构颁发的证书。 测试签名会验证驱动程序映像是否已签名,但在内核模式下执行的证书路径验证不需要将颁发者配置为受信任的根颁发机构。 这样,组织就可以根据组织内为代码签名颁发的凭据,在测试二进制文件上使用单个签名。 Microsoft建议这种形式的部署,以便在内核模式代码签名中进行测试签名。
对于测试签名,也可以使用由 makecert.exe 工具生成的证书。 但是,makecert 生成的证书通常不提供有用的标识信息,并且无法跟踪哪些开发人员创建了预发行二进制文件的测试签名版本。
注意 Windows Vista Beta2 版本仅接受生成证书工具生成的测试证书。 适用于测试签名的企业 CA 颁发的测试代码签名证书在 Windows Vista Beta2 中不可用。
本文档中的 Signtool 说明的工作方式与你使用的是 SPC、由 makecert 实用工具生成的证书,还是使用企业 CA 颁发的证书一样。 唯一的区别通常是证书中的颁发者和使用者名称。
测试签名还支持 WHQL 测试签名计划。 计划的参与者可以提交 WHQL 测试签名的驱动程序包。 测试签名目录上的签名由Microsoft测试根机构下颁发的证书生成。 默认情况下,Windows Vista Beta2 接受Microsoft测试根机构作为 beta 程序的一部分。 在 Windows Vista 的最终版本中,当 Windows Vista 启动配置设置启用测试签名时,将接受Microsoft测试根颁发机构。
默认情况下,测试签名的内核模式二进制文件不会在 Windows Vista 系统上加载。 默认情况下,测试签名二进制文件上的数字签名在 Windows Vista 系统上无效,因为内核模式代码签名策略不接受并且不信任测试签名证书。
启用测试签名
使用 Bcdedit 命令行工具启用测试签名。 若要使用 BCDedit,用户必须是系统上的 Administrators 组的成员,并从提升的命令提示符运行该命令。 可以通过创建桌面快捷方式来启动提升的命令提示符,以 cmd.exe,然后使用右键单击并“以管理员身份运行”。
下面显示了在命令提示符处运行 BDCedit 的示例:
// Accept test signed kernel mode signatures
Bcdedit.exe –set TESTSIGNING ON
// Do not accept test signed kernel mode signatures
Bcdedit.exe –set TESTSIGNING OFF
TESTSIGNING
启动配置选项确定 Windows Vista 是否接受测试签名的内核模式二进制文件。 此选项默认未定义,这意味着测试签名内核模式驱动程序上的数字签名不会验证,也不会加载。 当 Windows Vista 接受测试签名内核模式二进制文件时,系统可能无法访问受保护的某些高级内容。
故障 排除
可以采取特定步骤来识别和排查与验证内核模式代码签名相关的潜在问题。 本部分提供有关排查驱动程序签名强制问题的信息。 排查驱动程序签名问题的主要工具如下:
- 检测驱动程序加载错误
- 启用代码完整性诊断系统日志事件。
Windows Vista WDK 中包含的烤箱应用程序用作示例。 可以在“src\general\chef”目录下的 WDK 中找到烤箱应用程序。
检测驱动程序加载错误
烤箱应用程序安装设备驱动程序(toaster.sys),本示例未签名。 未签名驱动程序出现问题的症状是烤箱设备无法启动。 使用设备管理器,可以检查烤箱设备的状态并查看驱动程序状态,如以下屏幕图像所示。
图 1. 未签名的驱动程序错误
设备无法启动,因为设备驱动程序未签名,内核模式签名强制阻止驱动程序加载到内核中。 为了明确确定问题的根源,我们设置了系统,以便启用签名强制诊断,如下所示。
启用代码完整性诊断系统日志事件
内核模式代码签名强制实施由称为代码完整性的 Windows Vista 组件实现。 当内核模块的签名无法正确验证时,代码完整性将生成诊断事件和系统审核日志事件。
- 始终启用代码完整性操作事件。 加载内核模式二进制文件时图像验证检查失败时,操作事件是警告事件。
- 启用系统审核策略时,将生成代码完整性系统审核事件。 默认情况下,系统审核策略未启用。
- 代码完整性详细事件是分析和调试信息事件,显示加载内核模式二进制文件时所有成功的图像验证检查。 默认情况下不启用详细事件。
代码完整性事件在事件查看器下可查看,该事件是计算机管理 MMC 管理单元的一部分。 (在“开始”按钮中,右键单击 计算机,然后选择“管理”。
代码完整性事件流位于以下层次结构下:
事件查看器 -> 应用程序和服务日志 -> Microsoft -> Windows -> CodeIntegrity
图 2. 代码完整性事件
代码完整性操作日志显示内核模式驱动程序在加载驱动程序时映像验证检查失败时内核生成的事件。 映像验证失败的原因可能有很多,包括:
- 驱动程序未签名,但由管理员和代码完整性安装在系统上不允许驱动程序加载。
- 驱动程序已签名,但驱动程序映像文件已修改或篡改,修改无效驱动程序签名。
- 从坏磁盘扇区读取设备的映像文件时,系统磁盘设备可能存在设备错误。
未签名或修改的驱动程序映像验证失败的操作日志条目如以下示例所示:
图 3. 操作日志条目
该事件表示无法加载烤箱驱动程序(toaster.sys),因为它未签名(或者尝试加载的 toaster.sys 图像与发布者数字签名的图像不同)。
以下代码完整性事件日志消息部分列出了所有代码完整性事件日志消息。
系统审核日志事件
当内核模式驱动程序的图像验证失败时,代码完整性会生成与操作警告事件对应的系统审核日志事件。 系统日志事件可以在 Windows 日志、系统日志视图下的“事件查看器”中查看。
可能无法在所有 Windows Vista 系统上启用系统审核事件。 使用本地安全设置 MMC 管理单元在“本地策略”审核策略设置下验证或启用“审核系统事件”。
详细日志中的信息性事件
所有内核模式图像验证检查的其他代码完整性信息性事件都可以使用详细事件视图。 这些事件显示系统上加载的所有驱动程序的成功图像验证。
启用代码完整性详细事件视图的步骤如下:
- 单击 操作 视图以显示当前 代码完整性事件(如果有)。
- 左键单击 代码完整性 节点以设置焦点。
- 右键单击 代码完整性 节点以获取上下文菜单。
- 选择 视图。
- 选择 显示分析和调试日志。
- 这会创建一个子树,其中包含另外两个节点:操作 和 详细 节点。
- 右键单击 详细 节点并选择 属性。
- 选择 常规 工作表,然后选择 “启用日志记录”选项。 这应启用详细日志记录模式。
- 重新启动系统以重新加载所有内核模式二进制文件。
- 重新启动后,打开 计算机管理 管理单元,并查看 代码完整性详细事件日志。
可以检查 toaster.sys 是否已正确签名,如下所示:
在这种情况下,toaster.sys 是 PnP 驱动程序,并在目录文件中命名(tstamd64.cat“\src\general\toast\toastpkg\toastcd”。 使用 SignTool 实用工具验证 toaster.sys 是否已使用以下命令正确签名目录:
Signtool verify /kp /c tstamd64.cat toaster.sys
驱动程序验证调试选项
在某些情况下,开发人员可能需要强制实施强制内核模式代码签名策略,即使附加了调试器。 例如,当驱动程序堆栈具有无法加载的未签名驱动程序(例如筛选器驱动程序)时,这可能会使整个堆栈失效。 由于附加调试器允许未签名的驱动程序加载,因此在附加调试器后,问题就会消失。 调试这种类型的问题可能很困难。 为了方便在这种情况下进行调试,代码完整性支持一个注册表项,即使附加了调试器,也可以将其设置为强制实施内核模式签名。
注册表中定义了两个标志,用于控制调试器下的代码完整性行为。 默认情况下不定义标志。
按如下所示创建注册表值:
Key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\CI
Value: DebugFlags REG_DWORD
可能的值:
-
00000001
允许调试中断调试器,并且允许使用g
加载未签名的驱动程序。 -
00000010
CI 将忽略调试器的存在,并且未签名的驱动程序被阻止加载。
任何其他值都会导致未签名的驱动程序加载 , 这是默认策略。
代码完整性事件日志消息
以下是记录到代码完整性操作日志的警告事件:
- “代码完整性无法验证文件 <文件名> 的图像完整性,因为无法在系统上找到文件哈希。
- “代码完整性检测到未签名的驱动程序。
- “此事件与软件质量监测(SQM)相关。
以下是记录到代码完整性详细日志的信息事件:
- “代码完整性在目录 <目录名称>中找到文件 <文件名> 的一组每页图像哈希。
- “代码完整性为映像嵌入证书中的文件 <文件名> 找到了一组每页图像哈希。
- “代码完整性在目录 <目录名称>中找到文件 <文件名> 的文件哈希。
- “代码完整性在映像嵌入证书中
找到文件 文件名的文件哈希。 - “代码完整性确定未签名的内核模块 <文件名> 加载到系统中。 请与发布者联系,查看内核模块的已签名版本是否可用。
- “代码完整性无法验证文件 <文件名> 的图像完整性,因为系统上找不到每页图像哈希集。
- “代码完整性无法验证文件 <文件名> 的图像完整性,因为系统上找不到每页图像哈希集。 由于附加了内核模式调试器,因此允许加载映像。
- “代码完整性无法验证文件 <文件名> 的图像完整性,因为系统上找不到文件哈希。 由于附加了内核模式调试器,因此允许加载映像。
- “代码完整性无法加载 <> 目录的文件名。
- “代码完整性已成功加载 <文件名> 目录。
资源
- 有关内核模式驱动程序数字签名的问题,请发送电子邮件至 signsup@microsoft.com。
- 适用于 Windows Vista 内核模式代码签名 的
Microsoft跨证书 - 启动配置数据编辑器常见问题解答
- MSDN SDK 文档中的
CryptCATAdminAddCatalog - 使用安全软件发布加密硬件部署验证码
- 适用于 Windows 的
调试工具 - Certmgr
- MakeCat
- Makecert
- SignTool
- Windows 驱动程序工具包 (WDK)
- Windows 徽标计划
- WHQL 测试签名计划
- Windows 平台 SDK 下载站点
- Windows Quality Online Services (Winqual)
- 代码签名最佳做法
- 在 Windows Vista 中的即插即用设备安装过程中 驱动程序包完整性
- Windows Vista 中受保护媒体组件的
代码签名