数字签名基础:对称加密与非对称加密、哈希函数的作用、数字签名的生成与验证流程

聊数字签名之前,得先把它的地基搞清楚。说白了,数字签名不是凭空冒出来的技术,它是「非对称加密」和「哈希函数」这两个东西组合在一起的结果。我当年刚接触这块时,总觉得签名就是加密的反向操作,后来踩了坑才明白——完全不是一回事。

对称加密 vs 非对称加密

先说说加密这件事。加密就是把明文变成密文,解密就是把密文变回明文。这个过程中,钥匙(密钥)是关键。

对称加密,顾名思义,加密和解密用的是同一把钥匙。就像你家里的大门,用一把钥匙锁上,也用同一把钥匙打开。优点是快,非常快。缺点是——钥匙怎么安全地交给对方?

我在项目中遇到过一个问题:两个服务之间要传敏感数据,如果用对称加密,得先把密钥告诉对方。那这个密钥本身怎么传?走网络?万一被截获,加密就形同虚设了。这就是对称加密的「密钥分发难题」。

非对称加密就不一样了。它有一对钥匙:公钥和私钥。公钥可以公开给任何人,私钥只有自己知道。用公钥加密的数据,只有对应的私钥能解开;反过来,用私钥加密的数据,只有对应的公钥能解开。

你想想看,这解决了什么问题?别人用我的公钥加密一段消息发给我,只有我能用私钥解密。中间就算有人拿到了公钥,他也解不开。密钥分发的问题,就这么绕过去了。

特性 对称加密 非对称加密
密钥数量 1 个(共享密钥) 2 个(公钥 + 私钥)
速度 快(适合大量数据) 慢(适合小数据)
密钥分发 困难(需要安全通道) 容易(公钥可公开)
典型算法 AES、DES、SM4 RSA、ECC、SM2
主要用途 数据加密传输 密钥交换、数字签名
我的习惯:实际项目中,很少只用一种加密。通常是「非对称加密」交换对称密钥,然后用「对称加密」加密实际数据。这叫混合加密,HTTPS 就是这么干的。

哈希函数的作用

哈希函数,很多人叫它「散列函数」。它的作用很简单:把任意长度的数据,压缩成固定长度的「指纹」。这个指纹有几个特点:

  • 不可逆:从哈希值推不出原始数据。你想想看,如果能推出来,那就不叫哈希了。
  • 抗碰撞:很难找到两个不同的数据,哈希值相同。理论上存在碰撞,但计算上不可行。
  • 雪崩效应:原始数据改一个比特,哈希值就面目全非。

哈希函数在数字签名里扮演什么角色?我直接说结论:它解决了「签名效率」和「签名长度」的问题。

你想啊,如果直接对整份文件做非对称加密签名,文件有多大,签名计算量就有多大。几百兆的文件,签名一次可能要好几秒,这谁受得了?

哈希函数把文件压缩成一个固定长度的摘要(比如 SHA-256 是 32 字节),然后只对这个摘要签名。这样一来,不管文件多大,签名计算量都是固定的。嗯,这里要注意:哈希函数的选择很关键。我曾经见过有人用 MD5 做签名哈希,结果被碰撞攻击打得体无完肤。现在行业标准是 SHA-256 或更高。

核心要点:哈希函数是数字签名的「减负器」。它把大文件变成小指纹,让非对称加密只处理小数据,既快又安全。

数字签名的生成与验证流程

好了,前面两个概念铺垫完了,现在来看数字签名到底怎么玩。我把它拆成两个阶段:签名生成和签名验证。

签名生成(发送方)

  1. 对原始数据做哈希运算,得到摘要(Digest)。
  2. 用发送方的私钥对摘要加密,得到签名(Signature)。
  3. 把原始数据和签名一起发给接收方。

你看,签名不是加密整个文件,而是加密文件的哈希值。这就是为什么哈希函数是数字签名的核心组件。

签名验证(接收方)

  1. 收到原始数据和签名。
  2. 对原始数据做同样的哈希运算,得到摘要 A。
  3. 用发送方的公钥解密签名,得到摘要 B。
  4. 比较摘要 A 和摘要 B。如果一致,签名有效;否则无效。

为什么会这样?因为只有持有私钥的人才能生成正确的签名。公钥解密成功,说明签名一定是用对应的私钥生成的。哈希值一致,说明数据没有被篡改过。

我曾经踩过的坑:有一次做证书链校验,发现签名验证总是失败。查了半天,原来是接收方用的哈希算法和发送方不一致——发送方用 SHA-256,接收方默认用 SHA-1。两边哈希值对不上,签名自然无效。所以,签名算法和哈希算法必须约定好,不能各玩各的。

数字签名能保证什么?

  • 完整性:数据没有被篡改。哈希值对不上,说明数据被动了手脚。
  • 真实性:数据确实来自声称的发送方。私钥只有发送方有,别人伪造不了。
  • 不可否认性:发送方不能抵赖。签名是用他的私钥生成的,他赖不掉。

这三个特性,正是启动校验和证书链绑定的根基。你想想看,如果固件启动时能验证签名,就能确认固件是官方发布的、没有被篡改过。这就是安全启动的核心逻辑。

知识体系图:数字签名核心流程

下面这张图把整个流程串起来了。我建议你多看几遍,把每个节点的作用记清楚。

数字签名生成与验证流程 发送方(签名生成) 原始数据 私钥 哈希运算 签名运算 网络传输:原始数据 + 签名 接收方(签名验证) 收到的数据 公钥 哈希运算 解密签名 比较两个摘要:一致则签名有效 验证通过 ✓
一句话总结:数字签名 = 哈希函数 + 非对称加密。哈希负责「压缩」,私钥负责「盖章」,公钥负责「验章」。三者缺一不可。