密码学入门(7):数字签名和证书
数字签名
在上篇文章我们知道了消息认证码无法防止否认。因为发送者 Alice 和接收者 Bob 两者之间共享同一个密钥,所以 Alice 和 Bob 都可以生成 MAC 值,因此 Alice 可以否认自己发送过这条消息, Bob 也无法向第三方证明消息确实来自 Alice。假设 Alice 想向 Bob 借钱,她向 Bob 发送了一条 100 100 100 万元借条的邮件,Bob 不能轻易相信这封邮件,因为 Alice 可以事后以“我不知道这张借条”为由来进行否认。
消息认证码无法防止否认的原因在于发送者和接收者共享一个密钥,所以我们需要发送者和接收者各自使用不同的密钥。Alice 使用自己的私钥通过消息生成一个“签名”,而 Bob 则使用一个公钥对签名进行验证,这样就可以确保只有 Alice 才能生成这个“签名”。我们把这种技术称为数字签名(digital signature)。
数字签名和公钥密码的结构非常相似,它们都有一个公钥和私钥。它们之间的区别在于,公钥密码用公钥加密,私钥解密;而数字签名用私钥签名,公钥验证签名。数字签名相当于把公钥密码反过来用。
由于公钥和私钥是配对的,用公钥加密的密文只能由配对的私钥才能解密,用私钥加密的密文只能由配对的公钥才能解密。所以如果用某个公钥成功解密了密文,就能证明这段密文是由与该公钥配对的私钥进行加密得到的。数字签名中使用私钥加密(签名,在这里加密的作用并不是为了保证机密性),因为只有持有私钥的人才能生成该签名,所以可以利用这个性质来实现签名的不可否认。
数字签名的方法
- 直接对消息签名:这种方法易于理解,但实际上不会使用这种方法,因为公钥密码对整个消息加密(签名)的速度很慢,而且主动攻击者 Mallory 可能可以利用数字签名攻击公钥密码(因为数字签名的签名过程类似于公钥密码的解密过程,所以公钥密码和数字签名最好使用不同的密钥对)。
- 对消息的散列值签名:为了解决直接对消息签名带来的问题,我们可以通过单向散列函数将消息变成更短的散列值,然后对散列值加密(签名)。
通过上图我们可以看到,Alice 将公钥