浅谈前后端请求加密与签名
最近在做服务请求加密相关的工作,于此记录下一些资料。
引言
网络中的请求安全问题一般有两个方面:
- 请求安全性:即服务端收到你的请求时,需要鉴别请求是否有效
- 数据保密性:请求数据可能会被抓包,为避免用户敏感数据被窃取,需要进行数据加密。
请求唯一性 - once, time|timestamp
这个主要是为了防止无限制重复请求。
我们可以给请求加一个once
字段(一个随机{数|字符串}
),每次接受请求时,检查once
是否存在,不存在直接拒绝。如果存在的话,我们把这个once
拿到缓存库去找,找得到,说明已经被使用过,拒绝该次请求;找不到,记录请求信息,把once
写入到缓存中,正常执行。
但是这样无限制的往缓存里面塞请求数据信息的话,对于流量大的网站,是不能接受的,总不能让缓存崩掉吧。所以每一个once
缓存都会设置过期时间,这个时间根据你的并发量决定(比如5 mins
),并发量高设置的时间就短,反之就长一点。
依靠缓存的自动过期还是很单一的,所以我们会在请求加上time|timestamp
字段一个时间戳
,服务器接收这个请求的时候,取出time
,如果服务端的当前时间戳与time
的差值大于过期时间的话,就直接拒绝该次请求;否则就进行下一步处理,如检查once
。
请求一致性|数据安全 - sign
主要用于数据防串改。
服务端和客户端约定一个签名生成算法,客户端请求前,调用签名算法,生成sign
,并且把sign
和请求参数一起发送给服务器。服务器拿到请求的时候,把sign
单独提取出来,用签名算法对其他请求参数进行签名,如果生成的签名和sign
一致,说明数据没有被串改,可以进行下一步处理。
主要的算法:
MD5
- 是信息摘要算法,不是加密算法
- 加密算法是可以解密的,换言之,我加密之后我是需要知道加密的内容的(可解密)。
- 但是
MD5
是不可逆的,没哟解密的说法,所以MD5
是可以用来生成唯一数据,校验数据是否被串改的(sha-1
类似)。
Base64
- 是编码规范,不是加密算法
- 这货主要是为了处理网咯传输里面不支持和不可见字符的问题。(比如前端用
JavaScript
转义请求参数中空格的转义和后端某些语言对空格的转义不一致,这时候就会用到) - 换言之,签名算法里面对数据的转义可以用
aes
- 对称加密算法
- 客服端和服务器端共同确定一个用来加密和解密的秘钥。然后客服端在请求服务器是通过该秘钥对数据进行加密,服务器端在接收到请求之后使用该秘钥对数据进行解密。
- 服务端和客户端需要公用一个秘钥,不安全。
rsa
- 非对称加密算法
- 服务器端生成公钥和私钥,把公钥发送给客户端。客服端在请求服务器是,通过公钥对数据进行加密。服务器端接收到请求之后,使用私钥对加密的数据进行解密。
- 虽然避免了泄露的隐患,但是加密数据较大时,效率低,且需要分段加密处理
一般来说,签名算法主要是保证数据的唯一性,你可以选用MD5
和Base64
。
一般是一下几种方式
- 请求数据拼接
- 请求数据排序,一般按字母排序
- 请求数据加盐,一般是随机字符串和时间戳,会以明文方式请求服务端
- 请求数据
base64
编码,防止转义字符 - 请求数据
md5
加密
数据加密一般通过rsa
算法利用公钥rsa_pu
生成私钥aes_key
,然后通过aes
算法利用私钥aes_key
对请求参数进行加密得到secret_Data
,然后把公钥rsa_pu
对私钥aes_key
加密得到secret_key
, 把secret_Data
和secret_key
一起发送给服务端,服务端通过私钥解密secret_key
得到aes_key
,然后通过aes
算法利用aes_key
解密secret_Data
得到请求数据。反过来,服务端要返回保密的请求信息也是差不多的思路,
- 利用非对称算法加密对称算法的秘钥生成秘钥密文,通过对称算法用私钥加密数据生成数据密文。
- 用非对称算法解密私钥密文得到私钥,通过对称算法用私钥解密数据密文得到加秘数据。
用户的身份认证 - token|Authorization
服务端需要知道发起者的身份信息。
这点就不用说了,一般我们会在用户登录之后返回给用户一个token
,之后的每一次请求都带上这个token
,服务端用过读取token
存取的信息鉴别用户身份。
主要的实现方式(我目前所接触到的):
cache
- 把用户的铭感信息存入到缓存中,通过读取缓存信息鉴别用户身份。
- 实现简单,用户数据高度保密
- 占用缓存资源,可能会滥用缓存,可能会被对手利用,无限制刷缓存
jwt
- 通过
jwt
保存用户铭感信息至 payload 中。读取payload
鉴别用户信息 - 业界潮流,相关库也比较多
- 一旦被抓包,用户数据会被泄露
- 通过
aes
等对称加密算法- 通过对称加密算法,对用户身份信息进行加密,读取解密之后的用户信息
- 用户数据保密性高,同时也不消耗服务器资源
- 好像没有
选用哪一种好?其实对我来说,以上三种方式都是合格的,因为用户身份认证的核心在于,只要这个token
是我们自己的服务器签发的(无法伪造),就没问题。就拿jwt
方式来说,虽然用户的数据(比如用户的id
,用户的身份scope
等信息)可能会被抓包获取到,但是抓包方无法伪造jwt
的活,那就是成功的(你还是要老老实实的请求我们的token
接口).
文章参考:
- 网络请求中常见的加密机制和加密算法理解