# 消息认证码与数字签名

消息认证码和数字签名技术通过带密钥的认证算法来保护消息完整性并认证身份；它们通常会用到消息摘要，但不是简单地“加密摘要”。

## 消息认证码

消息认证码（Hash-based Message Authentication Code，HMAC），利用共享密钥和密码学 Hash 函数构造认证值，对消息完整性（Integrity）和来源真实性进行保护。HMAC 不是对称加密算法，不提供机密性。

基本过程为对某个消息，利用提前共享的对称密钥和 Hash 算法进行处理，得到 HMAC 值。该 HMAC 值持有方可以向对方证明自己拥有某个对称密钥，并且确保所传输消息内容未被篡改。

典型的 HMAC 生成算法包括 K，H，M 三个参数。K 为提前共享的对称密钥，H 为提前商定的 Hash 算法（如 SHA-256），M 为要传输的消息内容。三个参数缺失了任何一个，都无法得到正确的 HMAC 值。

消息认证码可以用于简单证明身份的场景。如 Alice、Bob 提前共享了 K 和 H。Alice 需要知晓对方是否为 Bob，可发送一段消息 M 给 Bob。Bob 收到 M 后计算其 HMAC 值并返回给 Alice，Alice 检验收到 HMAC 值的正确性可以验证对方是否真是 Bob。

*注：例子中并没有考虑中间人攻击的情况，并假定信道是安全的。*

消息认证码的主要问题是需要提前共享密钥，并且当密钥可能被多方同时拥有（甚至泄露）的场景下，无法追踪消息的真实来源。如果采用非对称数字签名机制，则能有效地解决这个问题。

## 数字签名

类似在纸质合同上进行签名以确认合同内容和证明身份，数字签名既可以证实某数字内容的完整性，又可以确认其来源（即不可抵赖，Non-Repudiation）。

一个典型的场景是，Alice 通过信道发给 Bob 一个文件（一份信息），Bob 如何获知所收到的文件即为 Alice 发出的原始版本？Alice 可以先对文件内容进行摘要，然后用自己的私钥和签名算法生成签名，之后同时将文件和签名都发给 Bob。Bob 收到文件和签名后，用 Alice 的公钥和同一签名算法执行验签，并把验签过程绑定到收到的文件内容。如果验签通过，说明该文件确实由持有 Alice 私钥的一方签发，并且文件内容没有被修改过。这里的“签名/验签”不是通用的“私钥加密、公钥解密”；ECDSA、EdDSA 等签名算法本身就不存在解密步骤。

并非所有非对称加密算法都可以直接用来实现数字签名，实践中应使用标准化的数字签名算法和安全参数。当前常用算法包括 RSA-PSS、ECDSA（Elliptic Curve Digital Signature Algorithm）和 EdDSA 等。NIST FIPS 186-5 已将传统 DSA 保留为仅用于验证既有签名，不再推荐用于生成新签名。

除普通的数字签名应用场景外，针对一些特定的安全需求，产生了一些特殊数字签名技术，包括盲签名、多重签名、群签名、环签名等。

### 盲签名

盲签名（Blind Signature），1982 年由 David Chaum 在论文《Blind Signatures for Untraceable Payment》中[提出](http://www.hit.bme.hu/~buttyan/courses/BMEVIHIM219/2009/Chaum.BlindSigForPayment.1982.PDF)。签名者需要在无法看到原始内容的前提下对信息进行签名。

盲签名可以实现对所签名内容的保护，防止签名者看到原始内容；另一方面，盲签名还可以实现防止追踪（Unlinkability），签名者无法将签名内容和签名结果进行对应。典型的实现包括 RSA 盲签名算法等。

### 多重签名

多重签名（Multiple Signature），即 n 个签名者中，收集到至少 m 个（n >= m >= 1）的签名，即认为合法。

其中，n 是提供的公钥个数，m 是需要匹配公钥的最少的签名个数。

多重签名可以有效地应用在多人投票共同决策的场景中。例如双方进行协商，第三方作为审核方。三方中任何两方达成一致即可完成协商。

比特币交易中就支持多重签名，可以实现多个人共同管理某个账户的比特币交易。

### 群签名

群签名（Group Signature），即某个群组内一个成员可以代表群组进行匿名签名。签名可以验证来自于该群组，却无法准确追踪到签名的是哪个成员。

群签名需要一个群管理员来添加新的群成员，因此存在群管理员可能追踪到签名成员身份的风险。

群签名最早在 1991 年由 David Chaum 和 Eugene van Heyst 提出。

### 环签名

环签名（Ring Signature），由 Rivest，Shamir 和 Tauman 三位密码学家在 2001 年首次提出。环签名属于一种简化的群签名。

签名者首先选定一个临时的签名者集合，集合中包括签名者自身。然后签名者利用自己的私钥和签名集合中其他人的公钥就可以独立地产生签名，而无需他人的帮助。签名者集合中的其他成员可能并不知道自己被包含在最终的签名中。

环签名在保护匿名性方面也具有很多用途。

## 安全性

数字签名算法自身的安全性由数学问题进行保护。但在实践中，各个环节的安全性都十分重要，一定要严格遵循标准流程。

例如，目前常见的数字签名算法需要选取合适的随机数作为配置参数，配置参数使用不当或泄露都会造成安全漏洞和风险。

2010 年 8 月，SONY 公司因为其 PS3 产品在采用十分安全的 ECDSA 进行签名时不慎使用了重复的随机参数，导致私钥被最终破解，造成重大经济损失。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yeasy.gitbook.io/blockchain_guide/05_crypto/signature.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
