加签验签
# 概念
# 加签
用Hash函数把原始报文生成报文摘要,然后用私钥对这个摘要进行加密,就得到这个报文对应的数字签名。通常来说呢,请求方会把「数字签名和报文原文」一并发送给接收方。
1.A计算消息m的消息摘要,记为
2.A使用私钥(n,d)对加密,生成签名s ,s满足:
;
由于A是用自己的私钥对消息摘要加密,所以只用使用s的公钥才能解密该消息摘要,这样A就不可否认自己发送了该消息给B。
3.A发送消息和签名(m,s)
给B。
# 验签
接收方拿到原始报文和数字签名后,用「同一个Hash函数」从报文中生成摘要A。另外,用对方提供的公钥对数字签名进行解密,得到摘要B,对比A和B是否相同,就可以得知报文有没有被篡改过。
1.B计算消息m的消息摘要,记为;
2.B使用A的公钥(n,e)
解密s
,得到
3.B比较与,相同则证明
# 为什么需要加签验签
假设现在有A公司,要接入C公司的转账系统。在一开始呢,C公司把自己的公钥寄给A公司,自己收藏好私钥。A公司这边的商户,发起转账时,A公司先用C公司的公钥,对请求报文加密,加密报文到达C公司的转账系统时,C公司就用自己的私钥把报文揭开。假设在加密的报文在传输过程中,被中间人Actor获取了,他也郁闷,因为他没有私钥,看着天鹅肉,又吃不了。本来想修改报文,给自己账号转一个亿的,哈哈。这个实现方式看起来是天衣无缝,稳得一匹的。
但是呢,如果一开始,C公司把公钥发给公司A的时候,就被中间人Actor获取到呢,酱紫就出问题了。
中间人Actor截取了C的公钥,他把自己的公钥发给了A公司,A误以为这就是C公司的公钥。A在发起转账时,用Actor的公钥,对请求报文加密,加密报文到在传输过程,Actor又截取了,这时候,他用自己的私钥解密,然后修改了报文(给自己转一个亿),再用C的公钥加密,发给C公司,C公司收到报文后,继续用自己的私钥解密。最后是不是A公司的转账账户损失了一个亿呢~
C公司是怎么区分报文是不是来自A呢,还是被中间人修改过呢?为了表明身份和报文真实性,这就需要「加签验签」啦!
A公司把自己的公钥也发送给C公司,私钥自己保留着。在发起转账时,先用自己的私钥对请求报文加签,于是得到自己的数字签名。再把数字签名和请求报文一起发送给C公司。C公司收到报文后,拿A的公钥进行验签,如果原始报文和数字签名的摘要内容不一致,那就是报文被篡改啦~
有些朋友可能有疑问,假设A在发自己的公钥给C公司的时候,也被中间人Actor截取了呢。嗯嗯,我们来模拟一波Actor又截取了公钥,看看Actor能干出什么事情来~哈哈
假设Actor截取到A的公钥后,随后也截取了到A发往C的报文。他截取到报文后,第一件想做的事肯定是修改报文内容。但是如果单单修改原始报文是不可以的,因为发过去C公司肯定验签不过啦。那么 Actor 自己修改后重新签名下呢?首先 A 和 C 使用的 hash 函数 Actor 不知道,如果 Actor 知道,那么他也没有 A 的私钥,生成了正确的摘要了,也是没有办法对摘要进行私钥加密的。签名不对 C 始终是不会使用这份报文的。
所以呢,公钥与私钥是用来加密与解密的,「加签与验签是用来证明身份」,以免被篡改的,防止被抓包然后改了数据。