互联网是一个开放的环境,危险无处不在,加密通信是安全的基础。但是只加密能解决所有问题吗?
举个例子,A正在某银行网站给B转账,转入卡号和金额输入完成后生成请求报文,然后加密报文传送给银行后台。银行收到请求后,解密得到明文,然后解析得到B的卡号和转账金额等信息,继续走后续转账流程。
正常我们会想,既然请求报文已经加密,按理说不应该会有安全问题。但实际上不是这么简单的。
如果传输使用对称加密算法(最常用的),客户端和服务端都是用同一个对称密钥,那么这个对称密钥就存在泄露的可能性。一旦泄露,攻击者X可以截获正常的报文,解密后替换卡号和金额,然后重新用同一个密钥加密被篡改的报文,发送给银行。银行解密后得到的是攻击者X的卡号,然后A的钱就到了X的账户了。
如何避免这种情况的发生,最直接的办法就是加强密钥的管理,防止泄露。方法有很多,可以每个报文都使用不同的对称密钥,做到一报一密。使用ECC椭圆算法实现客户端和服务端的密钥交换,从而避免密钥在网络上的传输。当然,还有一个办法就是给报文加签名。
签名,其实就是给报文做个摘要(哈希)。而且相同的签名算法得到的摘要是相同的,比如MD5,SH1,SH256等。简单的加签并不能真正的防篡改,因为攻击者可以篡改后,自己生成新的签名。服务端验签还是可以通过的。所以加签一定要包含一些特殊的私有的东西,比如个人私钥。
有了私钥签名,攻击者就不能轻而易举的修改签名。除非他拿到了私钥,但这种情况神也救不了你了。如果攻击者篡改报文,然后使用自己的私钥签名,服务端收到报文后,使用用户的公钥来验签,验签是失败的。这样就能保证用户的请求报文的安全性与完整性。