今天来说一下加解密相关的内容~

在这个后Rest时代,基本上HTTP API已经满大街了,如果你还不了解这个细节,或者你的项目不提供Rest API,你都不好意思来看我这篇文章~~
而通常我们简单的这些API,都不约儿童的包含了一个签名字段,主要目的是为了避免通信数据被恶意篡改,这也是https生而伟大的原因。

我们来进一步说一下这个签名逻辑:一般通信双方会提前约定好使用相同的一段字符串来作为签名的密钥,然后约定好使用的签名算法(例如md5),
然后双方在发送数据时,会把数据按照约定好的顺序拼接成一个字符串,然后再加上密钥,最后做个MD5就生成了一个签名字符串。

因为其他人不知道密钥,所以尽管他们能看到明文的通信数据,但他们无法生成相同的签名。同样,他们可以修改明文的数据,但也无法为修改后的数据
生成一个合法的签名。这样,只要接受数据的一方用接受到的明文数据+密钥做一次签名,然后和接受到的签名一比对,就知道数据是不是被篡改过了。

这并没有什么高深的思想,不过我们要注意一个细节:签名算法。一个比较好的签名算法,要求对碰撞几率足够低(即不同的字符串生成相同的签名值),
更要求签名不可逆性,最后也要保证签名性价比高(不能太慢,不能太耗资源)。

而签名的另外一个需要注意的细节是:传输过程中数据是明文的。为何必须要包含明文呢?

那么,如果传输的数据比较敏感呢?例如银行密码。那么只是签名肯定就是不够的了。这个时候就要对数据进行加密了。
常见的加密类型分为:对称加密,和非对称加密。对称加密比较好理解,通信双方约定好使用相同的密钥,然后在传递数据之前,对所有数据进行加密即可。
这样,只要密钥是安全的,中间人即便是抓包看到通信携带的数据,也因为无法解密而不能识别数据的含义。

听起来,岂不是不管三七二一,加就对了。那为何支付宝啊,微信啊,它们的接口都使用签名方式呢?
这个问题留给大家自己琢磨吧,我们今儿的主题不是它~

下面继续说一下非对称加密,这就有点意思了。一言以蔽之就是,加密和解密的时候需要使用不同的密钥来完成。神奇吧,什么?不知道这用来干啥么?
举个例子,假如请求方的密钥泄露了,是不是知道这个密钥的人都可以解密数据了?而非对称加密就能解决这个问题,牛逼吧!

那么,听起来,岂不是不管三七二一,非对称加就对了?那为何。。。(哎呀,别打我~)
其实冷静后不难得出,它们各自有各自的价值。

需要注意的是,非对称加密最安全,但性能越最低,然后是对称加密,然后是签名。所以如果用在接口上,考虑到并发量,还是需要根据具体场景具体分析的。

另外,如果你最终就是选择使用非对称加密来保护你的数据,你还要注意一点是,非对称加密对被加密的数据容量有限制,所以并不是想用就用的。
不过也别灰心,我们可以将它们结合在一起来使用:

  1. 使用创建的随机的AES对称加密算法使用的key对目标字符串进行对称加密
  2. 使用私钥对创建的随机key进行非对称加密

这样就可以避免数据量的问题。

不过我实际测试了一下,性能确实不理想啊。。。
如果你对数据的明文传输并不介意,但想要一个非对称的签名,那就既能保证足够的安全,性能也可以照顾到了。
幸运的是,RSA已经提供了这种非对称签名的实现,对这篇文章提到的内容有实战需求的朋友,可以看一下这个库:

https://github.com/kazaff/CipherUtils

参考文献

https://niels.nu/blog/2016/java-rsa.html
https://www.novixys.com/blog/using-aes-rsa-file-encryption-decryption-java/
https://blog.csdn.net/qq_32523587/article/details/79146977