使用 SignTool 进行代码签名

代码签名证书

代码签名证书 (Code Signing Certificate) 是为软件开发者提供的一种数字证书, 用于对二进制文件、VB 脚本等进行数字签名。它的主要作用是验证开发者的身份真实性, 并保护代码的完整性。用户在下载软件时, 能够通过数字签名验证软件来源是否可信, 并确认软件没有被非法篡改。

代码签名证书类型

代码签名证书分为两种类型: OV (Organization Validation)EV (Extended Validation)

  • EV 证书: 仅限企业购买, 私钥存储在USB 密钥中, 支持驱动程序签名。EV 证书的优势是, Microsoft SmartScreen 会直接信任使用 EV 签名的软件
  • OV 证书: 个人也可以申请, 私钥可以存储为文件, 但不支持驱动程序签名。使用 OV 证书的软件会通过累计下载数量逐渐获得 Microsoft SmartScreen 的信任

软件信誉与杀毒软件

证书主要用于身份识别, 各家杀毒软件有自己的数据库和病毒算法, 因此, 证书并不能成为免杀的 “金牌”。目前流行的安装方式是在线安装, 在这种情况下, 在线安装的 EXE 文件哈希值 (hash) 通常是固定不变的。再通过这个 EXE 下载安装程序, 可以绕过浏览器和 Microsoft SmartScreen 的拦截。

Microsoft SmartScreen

注意: Microsoft SmartScreen 与杀毒软件无关, 它只是用于检测下载的软件是否为可信的

  • 没有证书的软件通常依赖于软件的 hash 值来积累信誉, 缺点是这种信誉会随着软件更新而改变, 因为更新后的 hash 值不同需要重新累计信誉
  • 有证书签名的软件, 其信誉是累计在证书上的, 即使更新软件 hash 变动后任然可信

不同的杀毒软件有自己的数据库和病毒检测算法, 因此它们的信任标准不同。例如

  • 360 毒瘤: 360 会在自己的数据库中通过 hash 值判断软件是否在白名单中 (交保护费), 如果不在白名单中, 就会报毒
  • 卡巴斯基: 通过证书信誉来判断软件是否可信, 某些未签名但使用人数多的软件也会被卡巴斯基信任

卡巴斯基为例, 以下两个软件都没有签名

  1. ffmpeg.exe 虽然没有签名, 但因使用人数众多, 已经达到了卡巴斯基的信任门槛, 因此被认为是可信的

    ffmpeg_reputation.png

  2. JiJiDownForWPF.exe 没没有签名且发布时间较短, 用户数量少, 因此未能获得杀毒软件的信任

    JiJiDownForWPF_reputation.png

当没有进行混淆加密时, 未签名的程序通常不会被报毒。以下两个软件在开启混淆加密和加壳后进行签名

  1. aria2c.exe 使用人数较少, 而且使用 UPX 压缩。对其进行签名后, 卡巴斯基则显示为信任

    aria2_reputation.png

  2. N2NGUILauncher.exe 进行了混淆拉满、字符串加密、NecroBit 和防反汇编开启, 对其进行签名后卡巴斯基信任了, 而微软和 360 仍然会报毒。更新后的 360 版本不再报毒, 而旧版 360 则会报毒。

    N2NGUILauncher_reputation.png

    N2NGUILauncher_report.png

总的来说, OV 签名并不会直接绕过所有杀毒软件的检测, 具体结果还要根据各家杀毒软件的数据库。它的好处在于, 一旦证书被杀毒软件信任, 后续软件更新就不再容易被误报

购买代码签名证书

Comodo Code Signing Certificates 这家的代码签名证书是目前最便宜的。证书链由 Sectigo 提供, Sectigo 是 Comodo CA 的新名称

Sectigo (AAA)
└──Sectigo Public Code Signing Root R46
   └──Sectigo Public Code Signing CA R36
      └── 证书名字

你可以使用 OpenSSL 手动生成 ECC 的代码签名 CSR 文件, 具体步骤可参考 使用 OpenSSL 手动生成 CSR 文件

签名工具

你可以使用 signtool.exe 进行代码签名。常用的签名方式包括

  • SHA1 签名 (已淘汰, 如果需要支持 Windows 7 以下版本的系统, 程序需要 sha1 签名)

    "C:\Program Files (x86)\Microsoft SDKs\ClickOnce\SignTool\signtool.exe" sign /t http://timestamp.comodoca.com/authenticode file.exe
    
  • SHA256 签名 (2022 年当前推荐方式)

    "C:\Program Files (x86)\Microsoft SDKs\ClickOnce\SignTool\signtool.exe" sign /tr http://timestamp.sectigo.com?td=sha256 /td sha256 /fd sha256 /as file.exe
    
  • SHA384 签名

    "C:\Program Files (x86)\Microsoft SDKs\ClickOnce\SignTool\signtool.exe" sign /tr http://timestamp.sectigo.com?td=sha384 /td sha384 /fd sha384 /as file.exe
    

SHA1 和 SHA256 双签名

只需要先执行 SHA1 签名, 然后再执行 SHA256 签名, 就实现双重签名了

# 先 SHA1 签名
"C:\Program Files (x86)\Microsoft SDKs\ClickOnce\SignTool\signtool.exe" sign /t http://timestamp.comodoca.com/authenticode file.exe

# 再 SHA256 签名
"C:\Program Files (x86)\Microsoft SDKs\ClickOnce\SignTool\signtool.exe" sign /tr http://timestamp.sectigo.com?td=sha256 /td sha256 /fd sha256 /as file.exe

时间戳服务器 (time-stamping server)

代码签名时, 需要使用到时间戳服务器, 它为签名提供时间戳, 即使证书过期了, 在证书有效期内签名的程序仍然有效。

时间戳服务器地址不用和颁发证书的机构对应, 常见的时间戳服务器包括

http://timestamp.globalsign.com/scripts/timstamp.dll  # 不稳定
http://timestamp.comodoca.com/authenticode
http://timestamp.sectigo.com
http://timestamp.sectigo.com?td=sha256
http://timestamp.sectigo.com?td=sha384
http://www.startssl.com/timestamp
http://timestamp.digicert.com?alg=sha1
http://timestamp.digicert.com?alg=sha256

验证数字签名

你可以右键单击应用程序并选择 “属性” 来验证应用程序是否已签名。如果签名存在, 你可以在 “数字签名” 选项卡中查看签名证书和时间戳

aria2_verify_signature.png

这样, 你可以确保下载的软件是可信的, 并且未被篡改


原文

Authenticode Code Signing with Microsoft SignTool
SignTool 微软文档
signtool failing to dual sign SHA2 and SHA1 with timestamps
Time Stamp Server & Stamping Protocols for Digital Signatures/Code Signing
RFC3161 compliant Time Stamp Authority (TSA) server
Alternative timestamping services for Authenticode

最后更新于 2022-03-16
使用 Hugo 构建
主题 StackJimmy 设计