加密方案:AES + RSA两种加密方式混合使用,能够实现数据的全程加密(无论是上传,还是拉取)。
1、从客户端动态生成16位AES密码
2、使用第一步生成的AES密码加密要上发的请求数据,由于AES加密后是byte[]数据,所以这里还需要使用base64封装一层以方便传输。格式大概如下:
3、使用RSA公钥加密第二步生成的数据中的key,从而实现对key的保密,RSA加密后生成的二进制数据同样还需要再使用base64封装一层以方便传输,客户端的加密过程到这里就基本完成,然后就可以将该请求发送到服务端了。(RSA公钥客户端持有,RSA秘钥服务端持有)
4、服务端收到了客户端发送过来的请求后,拿到key参数,即为RSA加密byte。
5、使用服务端持有的私钥解密第4步获取到的RSA加密byte。从而获取到了第二步时候的数据,同时需要base64解码data数据。也即拿到了AES的key。
6、获取到AES的key后,便可以使用其来解密第5步中的data字段,也就是客户端的真正请求数据。进而做相关操作,并生成相应返回值。
7、服务端返回值生成后,同样使用第5步获取到的key进行加密,并得到返回的data(同样的base64封装)。与客户端加密不同的是,服务端的返回中key字段是客户端的key字段加了rsa签名后的数据。格式大概如下。
8、使用服务端持有的私钥对从客户端传过来的key的二进制数据进行签名(以防止中间人攻击),然后将数据向客户端返回。
9、客户端拿到服务端的数据返回后,先使用本地持有的公钥验证签名。然后base64解码。
10、使用请求时候生成的key来解码第9步验证通过的数据,解码后便得到了服务器端的真正返回,至此流程大概就完成了。
最后我们来分析下,为什么说,这套方案是比较安全的。
首先我们假设客户端被反编译,那他能获取到什么呢,一个动态生成的rsa加密key吗,拿过来并没有卵用。不过他能拿到我们的客户端公钥,拿到公钥之后,他可以做两件事情,1、伪造一个客户端,发送请求。 2、可以用来验证任意请求是否来自我们的服务器。 这两种情况也就够他自己一个人玩玩,都无法构成威胁。
其次,我们假设他通过抓包,获取了到了我们某个用户的请求全过程。接下来他可能首先分析上行数据,得到的是一个rsa加密后的数据,同样我们假设他反编译了我们的客户端,并且拿到了公钥,然而他还是解不了我们的rsa加密。上行数据无法破解,那他接下来就要来分析下行数据了,下行数据封装比较简单,而他也有我们的公钥,完全可以验证通过,并长驱直入直接拿到了我们的AES加密串,可惜啊,可惜,下行数据中并没有AES的秘钥啊。
总结一下,这套方案要被破解,思路只有通过其他途径直接控制服务器,然后再拿到我们的私钥,那就死翘翘了。不过真到了服务器都被人家攻陷了,那人家还拿你私钥干嘛,人家直接在上面挂个木马来转接客户端请求不就可以了。综上所述,这其实是一套相当完美的前后端数据交互方案。