数字签名不仅可以实现消息认证码的认证和检测篡改功能,还可以预防事后否认问题的发生。由于在消息认证码中使用的是共享密钥加密,所以持有密钥的收信人也有可能是消息的发送者,这样是无法预防事后否认行为的。而数字签名是只有发信人才能生成的,因此使用它就可以确定谁是消息的发送者了。
特征
看一看数字签名的特征。假设A要向B发送消息。
在发送前A给消息加上数字签名。数字签名只能由A生成。
只要发送的消息上有A的数字签名,就能确定消息的发送者就是A。
B可以验证数字签名的正确性,但无法生成数字签名。
加密处理流程
数字签名的生成使用的是公开密钥加密。
公开密钥加密中,加密使用的是公开密钥P,解密使用的是私有密钥S。任何人都可以使用公开密钥对数据进行加密,但只有持有私有密钥的人才能解密数据。然而,数字签名却是恰恰相反的。
下面,我们就来看一看使用了数字签名的消息交换流程。首先由A准备好需要发送的消息、私有密钥和公开密钥。由消息的发送者来准备这两个密钥,这一点与公开密钥加密有所不同。
A将公开密钥发送给B。
A使用私有密钥加密消息。加密后的消息就是数字签名。
A将消息和签名都发送给了B。
B使用公开密钥对密文(签名)进行解密。
B对解密后的消息进行确认,看它是否和收到的消息一致。流程到此结束。
解说
生成的是“只能由持有私有密钥的A来加密,但只要有公开密钥,谁都可以进行解密的密文”。这个密文作为密码似乎没有任何意义。但是换一个角度来看就会发现,它可以保证这个密文的制作者只能是持有私有密钥的A。
在数字签名中,是将“只能由A来加密的密文”作为“签名”来使用的。严格来说,也有使用加密运算以外的计算方法来生成签名的情况。但是,用私有密钥生成签名、用公开密钥验证签名这一机制是相同的,所以为了方便我们就以上文的方式进行了说明。
在公开密钥加密中,用公开密钥加密的数据都可以用私有密钥还原。而本节讲解的数字签名利用的是用私有密钥加密的数据,用公开密钥解密后就能还原这一性质。也就是说,即使密钥的使用顺序不同,运行结果也都是一样的。并不是所有的公开密钥加密都具有这个性质,不过RSA加密算法是可以的。
能够用A的公开密钥解密的密文,必定是由A生成的。因此,我们可以利用这个结论来确认消息的发送者是否为A,消息是否被人篡改。
由于B只有公开密钥,无法生成A的签名,所以也预防了“事后否认”这一问题的发生。
公开密钥加密的加密和解密都比较耗时。为了节约运算时间,实际上不会对消息直接进行加密,而是先求得消息的哈希值,再对哈希值进行加密,然后将其作为签名来使用(请参考下图)
存在的问题
虽然数字签名可以实现“认证”“检测篡改”“预防事后否认”三个功能,但它也有一个缺陷。
那就是,虽然使用数字签名后B会相信消息的发送者就是A,但实际上也有可能是X冒充了A。
其根本原因在于使用公开密钥加密无法确定公开密钥的制作者是谁。收到的公开密钥上也没有任何制作者的信息。因此,公开密钥有可能是由某个冒充A的人生成的。
使用“数字证书”就能解决这个问题。
参考: 我的第一本算法书 5-9 数字签名