- 什么是数字签名?
- 数字签名中包含了哪些信息?
- 数字签名的应用场景
- 数字签名与摘要(Digest)的关系
- 常说的“验签”是什么样的过程?
一、数字签名
💡数字签名是用私钥对数据的哈希值(摘要Digest)进行加密的过程。
数字签名的信任链通常是分级的,越往上层的私钥,安全等级越高,存储方式越原始(离网)。
-
数字签名的私钥的层级决定了签名的“信任锚点”。
层级一:根私钥(Root Private Key)
- 用途:签发中间 CA 证书。
- 存储:极其严格。通常存储在离线硬件安全模块(HSM) 中,甚至是物理隔离的保险柜内。使用 秘密共享(Shamir''s Secret Sharing) 机制,由多人同时在场才能激活签名操作。绝对不存储在联网的服务器硬盘上。
层级二:中间/签发私钥(Issuing Private Key)
- 用途:实际签发最终实体证书(如网站证书、客户端证书)。
- 存储:存储在在线 HSM 或 云 HSM 中。这些设备专为高频率签名设计,具有防篡改设计,密钥无法被导出。
层级三:最终实体私钥(End-Entity Private Key)
- 用途:对业务数据(如代码、邮件、交易)进行签名。
- 存储:
- 高安全场景(银行、政务):存储在 USB Key(U盾) 或 智能卡 中,私钥不可导出。
- 常规场景(普通开发者):存储在本地磁盘,使用对称加密(基于口令)保护。
a. 数字签名中包含的信息
|
组成部分 |
说明 |
作用 |
|
签名算法标识符 |
明确指明使用了的算法组合。 例如: |
让验签者知道用什么算法来正确解密和验证,避免算法歧义。 |
|
摘要值(被加密的那份) |
对原始数据进行哈希计算后得到的固定长度值,再经过签名者私钥加密后的密文。 |
这是签名的核心。验签时用公钥解密得到此摘要值,与本地重新计算的摘要进行比对。 |
数字签名是对消息摘要进行私钥加密运算后,附带了算法标识和证书信息的结构体;而摘要、消息摘要、digest在密码学应用中均指同一概念——哈希算法输出的固定长度散列值。
*除了签名算法标识符和摘要值,证书链/证书引用、签名时间戳、原始数据/指针也是证书中通常包含的可选信息。
b. 数字签名的使用场景
|
场景 |
描述 |
涉及的私钥层级 |
|
TLS/SSL 证书签名 |
CA 机构对服务器证书进行签名,构建信任链。 |
CA 根证书私钥(最高层级)或 中间证书私钥。 |
|
JWT/OIDC |
在微服务架构或单点登录中,服务器使用私钥签发 JWT Token,客户端使用公钥验证。 |
认证服务器(Authorization Server)持有的 签名私钥。 |
|
Git Commit 签名 |
开发者在提交代码时使用 GPG 密钥对 commit 进行签名。 |
开发者个人持有的 GPG 私钥。 |
|
代码签名 |
开发者对 |
软件开发商持有的 代码签名证书私钥。 |
|
文档签名 |
PDF 文件、Word 文档、电子合同中的数字签名(如 Adobe Sign、DocuSign)。 |
个人或企业持有的 文档签名证书私钥(通常是 USB Key 或云签名服务)。 |
二、摘要 Digest
Digest、消息摘要、摘要、Message Digest、信息摘要,
在密码学与证书语境下,指的是同一个概念:哈希算法输出的固定长度结果值(Hash Value)
- 非对称加密(RSA/ECC)处理任意长度数据的效率低,有长度限制。因此对原文生成定长的摘要,不对原文直接加密;
- 证书的数字签名保护的是“摘要”,实现的是不可抵赖性,但由于哈希算法的特性(抗碰撞性),对原文的任何改动都会导致摘要完全不同,从而间接保护了原文的完整性;
三、数字签名与摘要的关系
消息摘要是数字签名的“原材料”;数字签名是对“原材料”进行“加工(加密)”后的“成品”。
四、"验签",证书验证
💡证书上的公钥是Subject的公钥,验签时解密签名用的公钥不是证书上的公钥,而是本地信任库中的上级CA证书的公钥。(验签时,所使用的公钥,来自于另一个“信道”)
数字签名:使用私钥对摘要(TBSCertificate的哈希)进行加密,加密后的结果是数字签名;
证书验签:使用本地信任库中的上级CA证书的公钥解密数字签名,得到摘要值A;使用相同的哈希算法基于TBSCertificate计算证书摘要值B;对比摘要值;
*一个证书是否合法,需要检验该证书是否由合法的上级CA颁发;
*验签除了有证书验签,还有例如mTLS通信时的握手验签,验证的是客户端的身份,二者验签的内容是不同的。
证书验证链:
|
验证步骤 |
使用的公钥来源 |
被验证的对象 |
结果 |
|
验证叶子证书 |
上一级(中间CA)证书的公钥 |
叶子证书的签名 |
信任叶子证书内的公钥 |
|
验证中间CA证书 |
根CA证书的公钥(来自本地信任库) |
中间CA证书的签名 |
信任中间CA证书 |
|
验证根证书 |
无(自签名,信任库预置) |
— |
信任锚 |
💡 证书验签时,所使用的公钥,来自于另一个“信道”
验签时用来解密数字签名的公钥,绝对不是从被验证的证书本身获取的,而是来自一个预先信任的、独立的外部来源
- 信任库的建立和更新属于安全运维信道,与日常的网络通信信道分离,从而避免中间人攻击;
- 信任链的起点(根证书)通过带外安全方式(操作系统厂商审核、物理分发、安全更新等)预先注入到信任库中。确保攻击者无法通过网络篡改或伪造来插入假公钥。
- 根证书是自己的信任锚(Trust Anchor),根证书的公钥被预置在操作系统、浏览器或软件的本地信任库中(比如 Windows 的“受信任的根证书颁发机构”存储区)。验签时使用这个预置的公钥验证根证书的自签名。
- 中间 CA 证书或叶子证书验签时使用的公钥来自上一级签发者证书,而上一级证书逐层向上一级验证……直到某个根证书,其公钥来自本地信任库。
拓展:叶子证书上的公钥
思考:叶子证书中的公钥是用来做什么的?
💡 “验签”不仅只有验证书上的数字签名,在mTLS过程中的“验签”验的数字签名是叶子证书的私钥对“握手消息摘要”的签名,证明的是发消息的客户端是证书上的客户端,解密握手消息摘要时用的是叶子证书上的公钥。在使用这个叶子证书上的公钥验签之前,服务器会先完成证书链上的所有上级CA的验签,是两部分的验签过程。
|
步骤 |
验证对象 |
使用的公钥 |
目的 |
|
1. 验证证书链 |
客户端证书本身的数字签名(即 CA 签在证书上的签名) |
上级 CA 的公钥 |
确认证书是合法 CA 签发的,未被篡改 |
|
2. 验证客户端身份 |
客户端对握手消息摘要的数字签名(即客户端实时生成的签名) |
客户端证书中的主体公钥 |
确认客户端确实拥有该证书对应的私钥 |
问:叶子证书中的公钥是用来做什么的?
证书被验证通过后,证明的是证书上的公钥属于证书中写明的Subject(实体),后续通信中,可以:
- 用这个公钥去加密发给该实体的数据(保密性 Confidentiality);
- 验证该实体用自己的私钥签名的数据(不可抵赖性 non-repudiation);
***叶子证书上的公钥在使用前,会需要先完整证书链的验证,即证明叶子证书的公钥属于证书上写明的实体。***
拓展:mTLS中的验签对象,“握手消息摘要”
在 TLS 1.2 和 1.3 中,CertificateVerify 消息的签名计算方式略有不同,但核心思想一致:
客户端对迄今为止所有握手消息的哈希值进行签名。(绑定了握手的唯一上下文,握手中有随机数)
- TLS1.2(RFC 5246):客户端会计算一个
handshake_messages的哈希,然后对其进行签名; - TLS1.3(RFC 8446):客户端会计算一个
Transcript-Hash的哈希,然后对其进行签名;

2290

被折叠的 条评论
为什么被折叠?



