🛡️ 第五章 什么是密码、数字签名、数字证书
📄 一句话概括

数字签名 = 先对内容算哈希,再用自己的私钥签那个哈希——它要证明的不是"内容没被看到",而是"内容是谁发的、有没有被改";这两件事必须分清,因为实现它们的算法完全一样。

📝 本节和前面几节的关系

5-3 已经埋下了伏笔:"公钥加密/私钥解密"是保密,"私钥签名/公钥验证"是认证——同一对钥匙,用法反过来。 5-5 补上了另一块:签名签的其实是哈希,不是原文。

这一节就是把这两块拼起来。拼好之后你会发现,本章后面一半的内容(证书、HTTPS、代码签名、邮件签名)用的都是这同一个结构。

一、四步流程:先摘要,再签名

数字签名(digital signature)的流程固定为四步:

  1. 对内容算哈希 —— 几百 MB 的文件变成 32 字节的指纹;
  2. 用自己的私钥"加密"这个指纹 —— 得到的这串东西就是签名;
  3. 把【原内容 + 签名】一起发出去;
  4. 对方用你的公钥解开签名得到指纹,再对收到的内容算一次哈希 —— 两个指纹一致,就同时说明了两件事:内容没被改过,而且这份内容确实出自持有对应私钥的人。

第 2 步为什么要绕一圈去签哈希,而不是直接签原文? 因为签名运算很贵(5-7 会实测它有多贵),而哈希把任意长度的内容压缩成固定 32 字节——于是"签一份 1 GB 的文件"和"签一句话"的成本完全一样。

二、动手 Demo:签名、验证、和一次篡改

priv = "PRIVATE-KEY-1307"        # 只有签名者持有
doc  = "转账 100 元给 alice"

h    = hashlib.sha256(doc.encode()).hexdigest()      # ① 算摘要
sigv = hashlib.sha256((h + priv).encode()).hexdigest()[:32]   # ② 用私钥签摘要

# 三、篡改:把 100 改成 900
doc2 = "转账 900 元给 alice"
h2   = hashlib.sha256(doc2.encode()).hexdigest()
sig2 = hashlib.sha256((h2 + priv).encode()).hexdigest()[:32]

实跑输出:

一、四步流程
  ① 对内容算哈希           内容 → 定长指纹
  ② 用【自己的私钥】加密这个指纹   指纹 → 签名
  ③ 把【内容 + 签名】一起发出去
  ④ 对方用【你的公钥】解开签名得到指纹,再对收到的内容算一次哈希,
     两个指纹一致 → 内容没被改,而且确实是你发的

二、实际算一遍
  内容        转账 100 元给 alice
  内容哈希    c613e35eb7dad98a8e890e124b8b92bc...
  签名        a5aa03ecbb5ee85716ed830682153156
  对方收到后:重新算内容的哈希 → c613e35eb7dad98a8e890e124b8b92bc...
  再用公钥验证签名 → 通过

三、改一个字符,签名立刻对不上
  被改的内容    转账 900 元给 alice
  新算的签名    bfafa9d163c0b0f6c23fcf000e7b0479
  原来的签名    a5aa03ecbb5ee85716ed830682153156
  → 不一致(100 变成 900,签名完全变样)
     改的人如果没有私钥,就算把内容改了,也造不出匹配的新签名。

四、三个概念别混:哈希、加密、签名
  技术          回答什么问题                用不用密钥
  哈希          内容有没有变                不用(谁都能算)
  加密          内容能不能被人看到          用(收件人的公钥)
  签名          是谁发的、有没有变          用(发件人的私钥)
  → 一句话:加密解决【保密】,签名解决【认证】,哈希解决【完整性】。

五、为什么先哈希再签,而不是直接签原文
  · 原文可能几百 MB,哈希只有 32 字节:签名成本与内容长度无关
  · 同一份内容用哈希再签,签名长度固定,便于存档与比对
  · 反过来说:只要哈希算法被攻破(如 MD5、SHA-1),
     基于它的签名也一起失效——这就是【加密的危殆化】。

六、电子签名不是数字签名(法律概念 vs 技术概念)
  说法            属于          含义
  电子签名        法律概念      电子形式的签名行为,范围很宽(含手写签名扫描件等)
  数字签名        技术概念      必须用密码学实现,可验证、不可抵赖
  → 法律上认可的【可靠电子签名】,通常要求落在数字签名这一类上。

读这个输出:

三、签名与加密的分工:一张对照表

谁用钥匙 谁验证 保护什么
加密 发送方用接收方的公钥 接收方用私钥 保密:中途没人看得懂
签名 发送方用自己的私钥 任何人有发送方公钥就能验 认证 + 完整性:是谁发的、有没有改

一个常被忽略的推论:签名不提供保密性。一份签了名的文件仍然是明文——任何人都能读,只是改不了、也冒充不了。所以真实业务里经常是"先签名、再加密"或者"既签名又加密",两者叠加使用。

四、⚠️ 2026 现状

30 秒实验

今天做两个动作,各 15 秒:

  1. 随便找一封带"数字签名"的邮件或文件(很多办公软件导出 PDF 时可以签名),看一眼它的签名属性面板:你会看到"签名者""签名时间""证书颁发者"这几栏。这一眼就把本节抽象的流程变成了具体界面——"签名者"就是你刚才理解的私钥持有者,"证书颁发者"是 5-4 的 CA。
  2. 想一个场景并回答:如果你把一份文件签了名发给对方,对方能不能读到内容?——能,签名不保密。那对方能不能改成别的金额再转发出去?——不能,改一个字签名就对不上。这两个答案合起来,就是"签名"和"加密"的分界线。

这一节要带走的一句是:加密保护的是"别人看不见",签名保护的是"别人赖不掉"——数字签名做的事,是把一个只有你能做的动作,变成一个全世界都能验证的证据。

常见误区

  1. 错误:签名就是把文件内容加密一遍。——纠正:签名不加密,文件是明文。准确的说法是"对内容的摘要做一次只有私钥能做的运算"——任何人拿到你的公钥都能验证这个签名,但没有任何人能伪造一个新的。这个区别的实用后果很直接:如果你需要内容保密,签名完全不够,还得另外加密(5-7);反过来,如果你只需要证明"是谁发的、有没有改",加密又是多余的。看清目的再选工具,别把两者混为一谈。

  2. 错误:有了数字签名,内容就一定是安全可信的。——纠正:签名证明的是"来源"和"完整",不证明"内容本身是善意的"。一个攻击者完全可以拿自己合法申请的证书,给一段恶意代码签名——签名验证全部通过。这正是真实世界里恶意软件常见的形态:"有签名"只说明"这不是中途被替换的版本",不代表"这个东西值得信任"。判断是否可信,还要看签名者是谁、以及这个签名者本身是否可信(5-13 会讲到代码签名的这个边界)。

  3. 错误:扫描一张手写签名贴到文件上,就等于完成了数字签名。——纠正:这是"电子签名"和"数字签名"的混淆。贴一张图片,任何人复制粘贴就完成了"伪造",而且改内容也不会留下痕迹——它没有密码学上的任何保证。数字签名必须由密码学实现:摘要 + 私钥运算。这其中有实际的法律差别:法律上认可的"可靠电子签名"(比如我国《电子签名法》的语境)通常要求满足密码学验证、身份可确认、内容改动可发现这几条——一张图片签名给不了这几条保证。

  4. 错误:验证签名需要把我的公钥保密地交给对方。——纠正:恰恰相反,公钥就是要公开的。签名的验证设计成"任何人都能做"——这正是它能被用作证据的原因:不需要额外的信任前提,只要有你的公钥,谁都能验证。 需要保密的只有私钥(它决定谁能"签")。这也是公钥的分发问题(5-3)能靠"直接公开"解决的原因——公开的是验证能力,保密的是签发能力。

自测三问(点开对答案) 1. 为什么签名要"先哈希再签"?直接签原文有什么问题? —— **直接签原文的问题是成本和长度**。**签名运算是大数模幂,价格按"运算次数"算**——**签一份 1 GB 的文件,如果直接签全文,就要把 1 GB 数据全部卷进这个昂贵的运算里**。**先算哈希把内容压成 32 字节,签名成本就与内容长度彻底脱钩**——**签一句话和签一部电影,价格一样。** **第二个好处是固定长度**:**签名值的大小是确定的,便于存档、比对、以及放进证书这类有长度约束的结构里**。**代价是"签名的安全性从此依赖哈希的抗碰撞性"**——**这也是 MD5、SHA-1 倒台时,所有基于它们的签名一起失效的原因**(5-5)。 2. "加密"和"签名"用的是同一套数学,为什么要分成两件事? —— **因为它们要回答的问题不同,而且这两个问题经常只有一个需要解决**。**加密回答"能不能被看见"**(**用接收方的公钥加密,只有接收方能解**);**签名回答"是谁发的、有没有被改"**(**用自己的私钥签,谁都能验,但谁都不能伪造**)。**实际场景里这两件事的出现频率不一样**:**软件发布、代码、文档只需要签名**(内容本来就是公开的,不需要保密);**而传输敏感数据只需要加密**(双方身份已经通过其他方式确认)。**把两者当成一件事,会同时犯两种错**:**用加密代替签名(以为"看不见"就等于"不能伪造"),或者用签名代替加密(以为"签了名"内容就保密了)。** 3. 为什么说"私钥保管不好,签名的法律效力就没了"? —— **因为数字签名能当证据,全部建立在"私钥只有本人持有"这个前提上**。**验证签名的逻辑是"只有持有私钥的人能生成这个签名",所以"看到这个签名"就可以推断"是那个人做的"**。**如果私钥被复制给了别人、写在没有口令保护的设备上、或者被前员工带走**——**这个推断就断了**:**签名仍然能验通过,但"是谁签的"已经无法确定**。**所以工程上对私钥的每一层保护——口令、硬件模块、按人分发、可单独吊销、定期轮换——都不是"额外的好习惯",而是签名有效性的组成部分**(这也是 5-12 里 SSH 密钥管理那一套做法的意义)。

相关笔记