<密码学应用>数字签名

基于对称密码系统和仲裁者的文件签名

这种方式顾名思义,就是基于信任一个有权、值得绝对信任的仲裁者Trent的签名方式,Trent和Alice共享私密密钥KA,和Bob共享私密密钥KB。这些密钥在协议开始前就建立好,并为了签名可以重复使用:

  1. Alice用KA加密她准备发给Bob的消息的声明,并发给Trent。
  2. Trent用KA解密消息。
  3. Trent把这个解密消息和收到的消息声明,一起用KB加密。
  4. Trent把这个加密的消息包发给Bob
  5. Bob用KB解密消息,这样他能读取到Alice发的消息和Trent的证书,证明消息来自Alice。

接下来根据签名需要的特点来分析这种方式的可靠性:

  • **签名是可信的。**Trent是可信的,并且知道消息是从Alice那边发来的。Trent的证书对Bob起证明作用。
  • 所以签名是不可伪造的。只有Alice知道KA(当然Trent也知道,但是大家都相信他),如果有人伪造,第2步Trent就会察觉。
  • **签名不可被重复使用。**如果Bob想把Trent的证书附加到另一个消息上,Trent就会要求Bob同时提供消息和Alice加密后的消息,Bob没有KA,那肯定不能提供加密后的消息了。
  • 签名不能被改变。理由和上面一样,Bob没有KA
  • 签名不能抵赖。Alice如果想抵赖,说他没有发那个消息,Trent的证书会说明她发了这个消息。

这个协议不是不可行,但是对于Trent来说很耗时。他必须在每一对人中间充当中间人,即使Trent只是个软件程序,这个耗时的操作也是通信的瓶颈。再者,这个协议整个都是基于相信Trent是绝对可靠的,如果Trent犯了一次错误,那么整个系统就不可信了,所有人签名都变得混乱。

使用公开密钥密码系统对文件签名

很好理解,就是用私钥加密,公钥解密,由于私钥是只有Alice自己持有的,所以只有她自己能签名,而所有人都能拥有Alice的公钥,所以所有人都能读取到这个签名,但是没办法伪造。

协议过程略。

这种方法不依赖Trent,省去了很多麻烦,所以比前面的好。

特点也很好理解:

  • 可信的。因为用Alice的公钥能解开,所以可以取信是来自Alice的。
  • 不可伪造。只有Alice有私钥,其他人都不能伪造。
  • 不可被重复使用。签名是文件的函数,并且不可能转换成另外的文件。(*这个不太懂)
  • 不能被改变。文件如果被改变,用Alice的公钥就不能验证。
  • 不可抵赖。如果用Alice的公钥能解开,Alice就不能否认这个文件来自她,

文件签名和时间标记

比如数字签名的是一个银行支票,如果没有时间戳,Bob可以一直用这个带签名的支票去银行取钱。

所以数字签名经常包括时间标记。把时间日期附在消息中,然后一起签名这个消息。银行就把这个时间存在数据库中,Bob第二次去取的时候,银行就会发现对应时间的支出已经进行过了。

使用公开密钥密码系统和单向散列函数对文件签名

公开密钥密码算法本身效率没那么高,对长文件签名效率很低。为了节约时间,数字签名协议经常和单向散列函数一起使用。Alice不对文件签名,而是对文件的散列值签名。单向散列函数和数字签名算法事先商量好:

  1. Alice产生文件的散列值
  2. Alice用私钥加密散列值,实现对文件的签名。
  3. Alice把文件和签名的散列值发给Bob。
  4. Bob用Alice发送的文件产生散列值,再用Alice的公钥解密已签名的散列值,进行对比,确认文件来自Alice。

这样计算速度大大提高。两个文件有相同160位散列值的可能性为1/2160但是如果用非单向的散列函数,就很容易产生多个文件散列值相同。

多重签名

比如Alice和Bob都要对一个文件签名,然后给Carol,如果不用单向散列的话,有两种方法:

  1. Alice和Bob分别对文件副本签名,结果就是签名消息是原文的两倍,太浪费空间了
  2. Alice先签名,Bob再对Alice的签名再签名,结果就是Carol要验证Alice的签名,必须先验证Bob的签名,太浪费时间了。

如果用单向散列函数,就容易多了:

  1. Alice对文件散列签名
  2. Bob对文件散列签名
  3. Bob把他的签名交给Alice
  4. Alice把文件、她的签名和Bob的签名一起交给Carol
  5. Carol验证

这样又节约空间,又节约时间。

抗抵赖和数字签名

这里有一个抵赖的可能性:

Alice故意把自己的私钥泄露,这样任何人都可以伪装成Alice签名,Alice就可以抵赖说以前某些签名不是自己签的,即使加上时间戳,她也可以声称自己的私钥在更早的时间就泄露了。

这里有一个通用的协议:

  1. Alice对消息签名
  2. Alice产生一个报头,报头中含有一些鉴别消息。把报头和签名的消息连接起来,再对连接起来的消息签名,然后把签名发给Trent(*疑惑:为什么又有Trent了,之前不是讨论Trent参与每次会话的方案比较费时吗?)。
  3. Trent验证外面的签名,并确认鉴别消息。他在Alice 签名消息中增加一个时间标记和鉴别消息。然后对所有的消息再签名,分别发给Alice和Bob
  4. Bob验证
  5. Alice验证,如果这个消息她没有发,应该会大喊大叫。

带加密的数字签名

这个其实就是公开密钥密码系统通信和数字签名结合起来,在数字签名外面再套一层公开密钥密码系统通信,也就是把数字签名用公开密钥密码系统来传递:

Alice用自己的私钥签名,再用Bob的公钥加密 : EB(DA(M))

Bob用自己的私钥解密,然后在用Alice的公钥验证签名 E(ADB(EB(DA(M)))) = M

重新发送消息作为收据

比如有以下这种场景:

Bob在接收了Alice发送的消息后,需要向Alice确认自己已经收到了消息,那么除了上述的过程还有这么一个过程:

Bob在收到消息得到明文后,用自己的私钥签字,然后用Alice的公钥加密,再发给Alice;

Alice拿到后,用自己的私钥解密,然后用Bob的公钥验证Bob的签名;

如果Alice接收到的消息和她传给Bob的相同,她就知道Bob准确接收到了自己的消息。

这样一个过程,同样的算法既用作加密又用作解密,就有可能被攻击。数字签名操作是加密操作的逆操作:

VX=EX and SX = DX —— S-签名 V-验证

现在有一个Mallory是持有自己的公钥和私钥的系统合法用户,想要窃取明文M:

  1. Mallory把Alice在第一步中发的消息记录下来,在某个时间发给Bob

  2. Bob收到消息后,以为是Mallory发过来的合法消息,于是就用自己的私人密钥解密,然后用Mallory的公钥来验证,得到这样一堆乱七八糟的东西:

    EM(DB(EB(DA(M)))) = EM(DA(M)) = MASS

  3. Bob继续执行协议,把按上面处理再发回去:

    EM(DB(MASS)) = EM(DB(EM(DA(M))))

  4. 这样Mallory拿到消息后,用自己的私钥解密,再用Bob的公钥加密,再用自己的私钥解密,就会得到DA(M),然后他再用Alice的公钥加密,这样他就得到明文M了

这个攻击流程之所以能成,是因为Bob在不知情的情况下用自己的私钥帮Mallory解密了。

阻止重新发送攻击

上述攻击能成的根本原因是签名和加密用的同一套算法,加密运算与签名/验证运算相同,解密运算和签名运算相同。解决方法也很好理解

  • 加上时间戳,这样不至于每次消息内容都相同
  • 单向散列函数也可以解决这个问题
  • 加密和签名不用同一套算法

对公开密钥密码系统的攻击

针对公开密钥密码系统,公钥的保存是个极其重要的问题。比如把公钥存在一个数据库中,这个数据库所有人都可以从里面得到数据,但是也必须阻止除了Trent以外的人写入数据。否则Mallory就可以篡改数据,比如把Bob的公钥换成自己的,这样Bob读不到发给自己的数据,而Mallory可以。

阻止上述情况的方法是Trent用自己的私钥把所有公钥加密一遍,这时候Trent一般称为密钥鉴定机关或密钥分配中心(KDC),这样当Alice得到Bob的公钥的时候,用KDC验证一遍,以确认来源可靠。

但是这样,Mallory还是有办法,比如可以把自己的公钥替代那个密钥,然后破坏数据库,用自己的密钥替代有效密钥(就好像他自己是KDC一样)。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值