五、数字签名及存在的问题

章节系列目录:点击跳转

背景:A和B通信,X是中间人

数字签名

  上一篇我们说到了消息认证码可以防止假冒和篡改,而无法防止事后否认,这里我们会讲解数字签名为什么能解决这个问题。

  当我们用私钥加密的时候,我们会把这个操作称为数字签名,利用公钥解密的时候,这个操作称为验证签名

数字签名的方法流程是怎样的?

我看到了这样一张图,觉得太香了,能够很好的说明这个过程。

防止假冒

  中间人X假冒A给B发消息,由于X没有A的私钥,无法生成正确的数字签名。即使X不签名直接发过去,B也会直接丢弃,所以X无法假冒。

防止篡改

1.A给B发文档,先把文档进行哈希,生成摘要,然后用自己的私钥对摘要加密生成数字签名,发送出去的是 {明文文档,数字签名}
2.如果中间人X去修改明文,不改数字签名,发送给B。(因为没A的私钥,X如果改了签名,B用A公钥就无法解密数字签名)
3.B用A的公钥去解密数字签名得到摘要1,再用同样的哈希算法把发来的明文进行哈希,得到一段摘要2
4.摘要1一定是A亲手给的,因为公钥能解出来,摘要2是对明文哈希算出来的。
5.如果摘要1和摘要2对比不一样,那么这明文肯定是被篡改了。

事后否认

  当A要发送给B消息,会生成非对称密钥对,用A的私钥加密的东西只能用A的公钥解密,那么用A的公钥能解密的东西,只可能是A的私钥加密的了,就相当于A进行了签名,赖不掉的。当然需要数字证书才能真正安全,如果被中间人攻击了还防止事后否认,那可就是给自己挖坑,后面章节我们会讲解数字证书。

RSA生成和验证签名的过程

RSA生成签名

  在RSA中,被签名的消息、密钥以及最终生成的签名都是以数字形式表示的。在对文本进行签名时,需要事先将文本编码成数字。用RSA生成签名的过程可用下列公式来表述:

消息摘要 = hash(消息)
签名 = 消息摘要D mod N (用RSA生成签名)
这里的 {D, N} 就是签名者的私钥

RSA验证签名

验签解密的消息摘要 = 签名E mod N (用RSA验证签名)
由明文计算的消息摘要 = hash(明文消息)
这里 {E, N} 就是签名者的公钥。

if (验签解密的消息摘要 == 由明文计算的消息摘要)
    验证签名成功
else 
    验证签名失败

RSA签名和验证举例

  下面通过具体数字,用RSA实际生成和验证签名。

  先生成密钥对:
  公钥:E=5;N=323,即公钥 = {5, 323}
  私钥:D=29;N=323,即私钥 = {29, 323}
  假设消息摘要=hash(消息)=123
生成签名

签名 = 消息摘要D mod N
   = 12329 mod 323
   = 157
所以签名是157

验证签名:

验签解密的消息摘要 = 签名E mod N
             = 1575 mod 323
             = 123
所以验签解密的消息摘要是123

  如果消息没被篡改,那么由明文计算的消息摘要=hash(消息)=123

  验签解密的消息摘要=由明文计算的消息摘要,所以验证签名成功。这个明文消息就是由正确的发送者发来的。

为什么要加密摘要而不直接加密消息?

解决非对称密码处理速度慢的问题

  假如这个消息是一个很大的视频呢?非对称加解密本身就慢,大的视频更是难以操作,直接私钥加密消息得出来的数字签名非常大,而消息的哈希只是一串长度很有限的16进制数值,所以只加密消息的哈希而不是整个消息本身。如果你想检测签名是否有效,可以解密验证签名并自己对消息进行哈希转换(生成摘要),看看这两个值(摘要)是否匹配,这样我们就知道所接收的消息与服务器发送是否完全一样。如果消息在传输中被更改了,则哈希与服务器作为签名提供的值(摘要)不匹配,这叫做无效签名。

注意:一般来说,在采用具备同等机密性的密钥长度的情况下,非对称密码的处理速度只有对称密码的几百分之一。

防止利用数字签名攻击公钥密码

  这个话题怎么理解呢?假如有个中间人X有点low,在A和B通信过程中没法替换掉他们持有的对方的公钥,此时X想出了一招空手套白狼的方法。

  A想给B发送消息,然后用B的公钥加密发送给B,结果被中间人X拦截,然后X将这个密文消息作为附件发送给B,告诉B帮忙对此进行签名,实际上签名就是私钥密码的运算,相当于把A发给B的消息解密了。这样X就获取到了A发送给B的密文消息。

  我们不要对来历不明的消息进行签名,尤其是看起来像是随机数据的消息。

  所以我们对消息摘要进行签名会比较安全,不直接对消息签名也是避免了这种安全问题。

数字签名的漏洞

中间人攻击

A给B发消息会使用非对称加密,为了接下来的对话,先要把公钥发送给B,结果被X中间人攻击了。
A:“我是A,这是我的公钥key_pubA,你收好” ----->B
X截获了这个请求,修改一下:“我是A,这是我的公钥key_pubX,你收好” ----->B
接着A发消息时用A的私钥签名,X截获后随便篡改别的信息再自己生成签名,而B拿着所谓的"A的公钥" key_pubX,B验证签名也不会有问题。
A找B借钱1000到A账户,结果被X修改为借钱5000到X账户,B验证签名没问题。
这样防止事后否认的特性给A挖了个大坑。

  中间人攻击的详细过程及示意图已在第三章讲解混合加密时已经说过了,如不理解,请返回看图。传送门

  从上面我们可以看到,要防止中间人攻击,就必须确认自己拿到的公钥是否真的属于自己的通信对象。那么应该怎么解决这个问题?就是数字证书 。下一章给大家讲解数字证书。


关注、留言,我们一起学习。

----------------------Talk is cheap, show me the code-----------------------
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页