针对游戏开发人员的验证码签名

数据身份验证对于游戏开发人员来说越来越重要。 Windows Vista 和 Windows 7 具有许多功能,例如家长控制,要求正确签名游戏以确保没有人篡改数据。 Microsoft Authenticode 使最终用户和操作系统能够验证程序代码是否来自正确的所有者,并且它未被恶意更改或意外损坏。 本文讨论如何开始对游戏进行身份验证以及如何将身份验证集成到日常生成过程中。

注意

自 2016 年 1 月 1 日起,Windows 7 及更高版本不再信任任何 SHA-1 代码签名证书,到期日期为 2016 年 1 月 1 日或更高版本。 有关详细信息,请参阅 Windows 强制验证码代码签名和时间戳

背景

数字证书用于建立作者的身份。 数字证书由受信任的第三方颁发,称为证书颁发机构(CA),例如 VeriSign 或 Thawte。 CA 负责验证所有者是否未声明错误标识。 向 CA 申请证书后,商业开发人员可以在不到两周内对其应用程序做出响应。

CA 决定满足其策略条件后,会生成符合 X.509 的代码签名证书,该证书格式由国际电信联盟创建的行业标准证书格式(版本 3 扩展)。 此证书标识你并包含公钥。 它由 CA 存储以供参考,并电子形式提供给你一个副本。 同时,还创建一个私钥,你必须保持安全,并且你不得与任何人共享,甚至 CA。

拥有公钥和私钥后,可以开始分发已签名的软件。 Microsoft提供了在 Windows SDK 中执行此操作的工具。 这些工具利用单向哈希,生成固定长度的摘要,并使用私钥生成加密签名。 然后将该加密签名与证书和凭据合并到称为签名块的结构中,并将其嵌入可执行文件的文件格式。 任何类型的可执行二进制文件都可以签名,包括 DLL、可执行文件和内阁文件。

可以通过多种方式验证签名。 程序可以调用 CertVerifyCertificateChainPolicy 函数,并且可以使用 SignTool (signtool.exe) 从命令行提示符验证签名。 Windows 资源管理器在“文件属性”中还具有“数字签名”选项卡,用于显示已签名二进制文件的每个证书。 (“数字签名”选项卡仅显示在已签名文件的“文件属性”中。此外,应用程序可以使用 CertVerifyCertificateChainPolicy 进行自我验证

验证码签名不仅对最终用户的数据身份验证非常有用,而且对于修补受限用户帐户和 Windows Vista 和 Windows 7 中的家长控制,也需要验证码签名。 此外,Windows 操作系统的未来技术可能还需要对代码进行签名,因此强烈建议所有专业和业余开发人员从 CA 获取代码签名证书。 有关如何执行此操作的详细信息,请参阅本文后面的“ 使用受信任的证书颁发机构”。

通过验证文件在代码中是否真实,游戏代码、修补程序和安装程序可以进一步利用验证码签名。 这可用于反作弊和常规网络安全。 此处提供了用于检查文件是否已签名的示例代码: 示例 C 程序:验证 PE 文件的签名,以及检查已签名文件上签名证书所有权的示例代码,可在此处找到: 如何从验证码签名可执行文件获取信息。

入门

若要开始,Microsoft提供了 Visual Studio 2005 和 Visual Studio 2008 以及 Windows SDK 中的工具,以帮助执行和验证代码签名过程。 安装 Visual Studio 或 Windows SDK 后,此技术文章中所述的工具位于安装的子目录中,其中可能包括以下一个或多个:

  • %SystemDrive%\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin
  • %SystemDrive%\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Bin
  • %SystemDrive%\Program Files\Microsoft Visual Studio 9.0\SmartDevices\SDK\SDKTools\
  • %SystemDrive%\Program Files\Microsoft SDKs\Windows\v6.0A\bin\

以下工具最适用于签名代码:

证书创建工具(MakeCert.exe)

将测试 X.509 证书作为.cer文件生成,该文件包含公钥和私钥,作为 .pvk 文件。 此证书仅用于内部测试目的,不能公开使用。

pvk2pfx.exe

从一对 .cer 和 .pvk 文件创建个人信息交换 (.pfx) 文件。 .pfx 文件包含公钥和私钥。

SignTool (SignTool.exe)

使用 .pfx 文件对文件进行签名。 SignTool 支持对 DLL 文件、可执行文件、Windows Installer (.msi) 文件和 cabinet (.cab) 文件进行签名。

注意

阅读其他文档时,你可能会发现对 SignCode(SignCode.exe)的引用,但此工具已弃用,不再受支持—请改用 SignTool。

 

使用受信任的证书颁发机构

若要获取受信任的证书,必须应用于证书颁发机构(CA),例如 VeriSign 或 Thawte。 Microsoft不建议将任何 CA 用于另一个 CA,但如果要集成到 Windows 错误报告 (WER) 服务中,应考虑使用 VeriSign 颁发证书,因为访问 WER 数据库需要一个需要 VeriSign ID 的 WinQual 帐户。 有关受信任的第三方证书颁发机构的完整列表,请参阅 Microsoft根证书计划成员。 有关注册 WER 的详细信息,请参阅 ISV 区域中Windows 错误报告简介”。

从 CA 收到证书后,可以使用 SignTool 对程序进行签名,并将程序发布到公众。 但是,必须小心保护私钥,该私钥包含在 .pfx 和 .pvk 文件中。 请务必将这些文件保存在安全的位置。

使用测试证书的示例

以下步骤演示如何创建用于测试目的的代码签名证书,然后使用此测试证书对 Direct3D 示例程序(称为BasicHLSL.exe)进行签名。 此过程将分别创建.cer和 .pvk 文件(公钥和私钥),这些文件不能用于公共认证。

在此示例中,还会向签名添加时间戳。 时间戳可防止证书过期时签名变得无效。 签名但缺少时间戳的代码在证书过期后不会验证。 因此,所有公开发布的代码都应具有时间戳。

创建证书并对程序进行签名

  1. 使用证书创建工具(MakeCert.exe)创建测试证书和私钥。

    下面的命令行示例将 MyPrivateKey 指定为私钥 (.pvk) 文件的文件名,将 MyPublicKey 指定为证书 (.cer) 文件的文件名,将 MySoftwareCompany 指定为证书的名称。 它还使证书自签名,因此它没有不受信任的根颁发机构。

    MakeCert /n CN=MySoftwareCompany /r /h 0 /eku "1.3.6.1.5.5.7.3.3,1.3.6.1.4.1.311.10.3.13" /e 12-31-2020 /sv MyPrivateKey.pvk MyPublicKey.cer
    
  2. 使用pvk2pfx.exe从私钥(.pvk)文件和证书(.cer)文件创建个人信息交换(.pfx)文件。

    .pfx 文件将公钥和私钥合并到单个文件中。 以下命令行示例使用上一步中的 .pvk 和.cer文件创建名为 MyPFX 的 .pfx 文件,其密码your_password:

    pvk2pfx.exe -pvk MyPrivateKey.pvk -spc MyPublicKey.cer -pfx MyPFX.pfx -po your_password
    
  3. 使用 SignTool 使用个人信息交换 (.pfx) 文件对程序进行签名。

    可以在命令行上指定多个选项。 下面的命令行示例使用上一步中的 .pfx 文件,提供your_password作为密码,将 BasicHLSL 指定为要签名的文件,并从指定服务器检索时间戳:

    signtool.exe sign /fd SHA256 /f MyPFX.pfx /p your_password /v /t URL_to_time_stamp_service BasicHLSL.exe
    

    注意

    时间戳服务的 URL 由 CA 提供,可用于测试。 生产签名必须包含有效的时间戳颁发机构,或者签名在证书过期时无法验证。

     

  4. 使用 SignTool 验证程序是否已签名。

    以下命令行示例指定 SignTool 应尝试使用所有可用方法验证BasicHLSL.exe上的签名,同时提供详细输出:

    signtool.exe verify /a /v BasicHLSL.exe
    

    在此示例中,SignTool 应指示证书已附加,同时指出它不受信任,因为它不是 CA 颁发的。

  5. 信任测试证书。

    对于测试证书,需要信任证书。 对于 CA 提供的证书,应跳过此步骤,因为默认情况下这些证书将受信任。

    在仅想要信任测试证书的计算机上,运行以下命令:

    certmgr.msc
    

    然后右键单击“受信任的根证书颁发机构”并选择“所有任务” |进口。 然后浏览到创建的 .pfx 文件,并按照向导步骤将证书放置在受信任的根证书颁发机构中。

    向导完成后,可以使用该计算机上的受信任证书开始测试。

将代码登录集成到每日生成系统中

若要将代码登录项目集成,可以创建批处理文件或脚本来运行命令行工具。 生成项目后,使用正确的设置运行 SignTool(如示例中的步骤 3 所示)。

在生成过程中尤其谨慎,以确保访问 .pfx 和 .pvk 文件仅限于尽可能少的计算机和用户。 最佳做法是,开发人员应仅使用测试证书对代码进行签名,直到他们准备好交付。 同样,私钥(.pvk)应保存在安全的位置,如安全或锁定的聊天室,理想情况下保存在加密设备上,例如智能卡。

另一层保护是通过使用 Microsoft Authenticode 对 Windows Installer (MSI) 包本身进行签名提供的。 这有助于保护 MSI 包免受篡改和意外损坏。 有关如何使用 Authenticode 对包进行签名的详细信息,请参阅 MSI 创建工具的文档。

撤销

如果私钥的安全性遭到入侵或某些与安全相关的事件导致代码签名证书无效,开发人员必须吊销证书。 这样做会削弱开发人员的完整性和签名代码的有效性。 CA 还可以使用特定时间发出吊销;在吊销时间之前使用时间戳签名的代码仍被视为有效,但具有后续时间戳的代码将无效。 证书吊销会影响使用吊销证书签名的任何应用程序中的代码。

代码签名驱动程序

驱动程序可以且应签名验证码。 内核模式驱动程序具有其他要求:64 位版本的 Windows Vista 和 Windows 7 将阻止安装所有未签名的内核模式驱动程序,当用户尝试安装未签名的驱动程序时,所有版本的 Windows 将显示警告提示。 此外,管理员可以设置组策略,以防止在 Microsoft Windows Server 2003、Windows XP Professional x64 Edition 和 32 位版本的 Windows Vista 和 Windows 7 上安装未签名的驱动程序。

许多类型的驱动程序可以使用Microsoft受信任的签名(作为 Windows 硬件质量实验室(WHQL)的 Windows 认证计划的一部分或未分类的签名计划(以前命名为驱动程序可靠性签名)进行签名,这允许系统完全信任这些驱动程序,即使没有管理凭据,也安装它们。

驱动程序至少应为 Authenticode 签名,因为未签名或自签名(即使用测试证书签名)的驱动程序无法在许多基于 Windows 的平台上安装。 有关对驱动程序和代码进行签名和相关功能的详细信息,请参阅 Windows 硬件开发人员 Central 上的 Windows 驱动程序签名要求。

总结

使用 Microsoft Authenticode 是一个简单的过程。 获取 CER 并创建私钥后,只需使用Microsoft提供的工具即可。 然后,你可以在 Windows Vista 和 Windows 7 中启用重要功能,例如家长控制,并让客户知道你的产品直接来自其适当的所有者。

详细信息

有关与签名代码相关的工具和过程的详细信息,请参阅以下链接: