时间戳验证码签名

Microsoft 验证码签名为二进制数据提供创作权和完整性保证。 验证码时间戳基于标准 PKCS #7 副署。 Microsoft 签名工具允许开发人员在贴上验证码签名的同时贴上时间戳。 时间戳允许在用于签名的证书过期后验证验证码签名。

验证码简介

验证码会应用数字签名技术,以确保二进制数据的创作权和完整性,例如可安装的软件。 客户端 Web 浏览器或其他系统组件可以使用验证码签名在下载或安装软件时验证数据的完整性。 验证码签名可以用于许多软件格式,包括 .cab、.exe、.ocx 和 .dll。

Microsoft 维护公共证书颁发机构 (CA) 的列表。 验证码证书的颁发者目前包括 SSL.comDigicertSectigo(Comodo)GlobalSign

关于加密时间戳

过去,提出了各种加密时间戳方法。 例如,请参阅《加密学杂志》(1991 年)以及 Benaloh 和 de Mare 编写的“单向积累器:数字签名的分散替代方法”,以及计算机科学 Springer-Verlag 讲座说明第 765 卷 (EUROCRYPT '93) 中 Haber 和 Stornetta 编写的“如何为数字文档添加时间戳”。 本文的扩展摘要可从 Microsoft Research 获取。 (这些资源可能在某些语言和国家或地区不可用。)由于时间是物理对象而不是数学数量,因此这些方法通常涉及如何链接对象,以便确定其创建顺序,或如何有效地对可描述为并发创建的对象进行分组。

声称以数量身份对时间进行身份验证的系统始终需要某种形式的信任。 在强对抗设置中,可以使用复杂协议来确保某种程度的同步。 但是,这些协议需要受影响各方之间的广泛交互。 实际上,如果一个人只需要从可信源获得时间认证,则源只需提供一份签名声明(认证),该对象在所指示的时间就可充当公证人。

以下实现的时间戳的副署方法允许在签名证书过期或吊销后验证签名。 时间戳允许验证程序可靠地知道签名所贴的时间,从而信任签名(如果签名在当时有效)。 时间戳签署人应具有可靠且受保护的时间源。

PKCS #7 签名文档和副署

PKCS #7 是加密数据的标准格式,包括签名数据、证书和证书吊销列表 (CRL)。 时间戳上下文中感兴趣的特定 PKCS #7 类型是签名数据,对应于定义的 SignedData 内容类型的 PKCS #7。

PKCS #7 包由 SignedData 组成,用于标识实际内容及其特定信息以及 SignerInfo 签名块。 SignerInfo 本身可能包含副署,从递归角度是另一个 SignerInfo。 原则上,可能存在此类副署序列。 副署是与 SignerInfo 中的签名相关的未经身份验证的属性;也就是说,它可能会在原始签名之后进行贴附。 在大纲窗体中:

SignedData (PKCS #7)

  • 版本(通常是 PKCS #7 版本 1)
  • DigestAlgorithms(SignerInfo 签名块用于优化处理的所有算法的集合)
  • ContentInfo (contentType 等于 SignedData,以及内容或对内容的引用)
  • 可选证书(使用的所有证书的集合)
  • 可选 CRL(所有 CRL 的集合)
  • SignerInfo 签名块(实际签名,由一个或多个 SignerInfo 签名块组成)

SignerInfo(签名块)

  • 版本(通常是 PKCS #7 版本 1)
  • 证书(用于在 SignedData 中唯一标识签名者证书的颁发者和序列号)
  • DigestAlgorithm 加上 DigestEncryptionAlgorithm 和摘要(哈希),以及 EncryptedDigest(实际签名)
  • OPTIONAL AuthenticatedAttributes(例如,由此签名者签名)
  • OPTIONAL UnauthenticatedAttributes(例如,未由此签名者签名)

经过身份验证的属性的一个示例是签名时间 (OID 1.2.840.113549.1.9.5),因为它是时间戳服务签名的一部分。 未经身份验证的属性的一个示例是副署 (OID 1.2.840.113549.1.9.6),因为它可以在签名后贴上。 在这种情况下,SignerInfo 本身包含 SignerInfo(副署)。

注意

在副署中签名的对象是原始签名(即原始 SignerInfo 的 EncryptedDigest)。

 

SignTool 和 Authenticode 进程

SignTool 可用于验证码签名和为二进制数据添加时间戳。 该工具安装在 Microsoft Windows 软件开发工具包 (SDK) 安装路径下的 \Bin 文件夹中。

使用 SignTool 对二进制数据进行签名和添加时间戳相对简单。 发行者必须从商业代码签名 CA 获取代码签名证书。 为方便起见,Microsoft 发布和更新公共 CA 的列表,包括颁发验证码证书的 CA。 准备好发布时,将使用相应的命令行参数和 SignTool 工具对对象文件进行签名和添加时间戳。 任何 SignTool 操作的结果始终为 PKCS #7 格式 SignedData

SignTool 接受要签名和添加时间戳的原始二进制数据作为输入,或者接受要添加时间戳的以前签名的二进制数据作为输入。 以前签名的数据可以通过使用 signtool timestamp 命令添加时间戳。

参数 说明
/t HTTPAddress 指示文件将添加时间戳。 必须提供指定时间戳服务器地址的 URL。 /t 可与 signtool signsigntool timestamp 命令结合使用。

 

有关可能在此上下文中有用的工具的详细信息,请参阅加密工具和SignTool

实现详细信息和线路格式

SignTool 依赖于 Windows 验证码实现来创建签名并添加时间戳。 验证码对二进制文件执行操作,例如 .cab、.exe、.dll 或 .ocx。 验证码首先创建签名,生成 PKCS #7 SignedData。 此 SignedData 必须进行副署,如 PKCS #9 中所述。

副署过程采用四个步骤进行:

  1. 从 PKCS #7 SignedData 的 SignerInfo 复制签名(即 encryptedDigest)。
  2. 构造内容为原始签名的时间戳请求。 将其发送到编码为 TimeStampRequest 的时间戳服务器抽象语法表示法一 (ASN.1)。
  3. 接收从时间戳服务器返回的第二个 PKCS #7 SignedData 格式的时间戳。
  4. 将 SignerInfo 从时间戳直接复制到原始 PKCS #7 SignedData 中,作为 PKCS #9 副署(即原始 SignerInfo 中的未经身份验证的属性)。

时间戳请求

时间戳请求在 HTTP 1.1 POST 消息中发送。 在 HTTP 标头中,CacheControl 指令设置为 no-cache,Content-Type 指令设置为 application/octet-stream。 HTTP 消息的正文是时间戳请求的可辨别编码规则 (DER) 编码的 base64 编码。

虽然当前未使用,但 Content-Length 指令还应用于构造 HTTP 消息,因为它有助于时间戳服务器查找请求在 HTTP POST 中的位置。

其他 HTTP 标头也可能存在,如果请求者或时间戳服务器无法理解它们,应将其忽略。

时间戳请求是 ASN.1 编码消息。 请求的格式如下。

TimeStampRequest ::= SEQUENCE {
   countersignatureType OBJECT IDENTIFIER,
   attributes Attributes OPTIONAL, 
   content  ContentInfo
}

countersignatureType 是对象标识符 (OID),用于将其标识为时间戳副署,应是确切的 OID 1.3.6.1.4.1.311.3.2.1。

时间戳请求中当前不包含任何属性。

内容是 PKCS #7 定义的 ContentInfo。 内容是要签名的数据。 对于签名时间戳,ContentType 应为 Data,内容应为要添加时间戳的 PKCS #7 内容的 SignerInfo 中的 encryptedDigest(签名)。

时间戳响应

时间戳响应也在 HTTP 1.1 消息中发送。 在 HTTP 标头中,Content-Type 指令也设置为 application/octet-stream。 HTTP 消息的正文是时间戳响应的 DER 编码的 base64 编码。

时间戳响应是由时间戳签署人签名的 PKCS #7 签名消息。 PKCS #7 消息的 ContentInfo 与时间戳中收到的 ContentInfo 相同。 PKCS #7 内容包含签名时间经过身份验证的属性(在 PKCS #99、OID 1.2.840.113549.9.5 中定义)。

验证码从服务器接收时间戳后,验证码会将时间戳作为计数器合并到原始 PKCS #7 SignedData 中。 为此,将丢弃返回的 PKCS #7 SignedData 的 ContentInfo,并将返回时间戳的 SignerInfo 作为副署复制到原始 PKCS #7 SignedData 的 SignerInfo 中。 时间戳签署人的证书链也作为原始签名者的未经身份验证的属性复制到原始 PKCS #7 SignedData 的证书中。