确保对外提供的API接口的安全性
分为三个方面:(参考链接https://blog.csdn.net/qq_35524157/article/details/116494536)
一、 确保调用者的合法性
二、确保数据传输过程的安全性
三、防篡改
一、 针对--调用者身份安全的校验方式:
- 高德地图方案:(apiKey + apiSecret)
- 提供签发服务,给api使用者提供 apiKey / apiSecret
- url携带apiKey, apiSecret 存储在nginx 上,通过nginx添加额外参数
- 每次请求接口携带 apiKey, apiSecret通过nginx追加参数
- 后端拿到 apiKey apiSecret,校验两者的匹配性
弊端: 以上只能确保访问 api的是合法用户,不能保证数据传输安全性
- apiKey + apiSecret 方式二:
- 服务端生成 apiKey / apiSecret 提供给客户端
- 客户端通过请求服务端时,生成签名 sign, 携带到请求参数中传递给服务端
- 服务端拿到签名后,通过约定好的算法规则生成签名,和客户端发送的签名对比
签名生成规则: 优势:签名验证第一可以验证 apiKey和apiSecret 的匹配性。二可以确保请求参数没有被篡改
弊端:apiSecret 保存在客户端代码里,不安全。
解决方案:使用代码混淆,使密钥难以获取。
二、 针对--数据传输安全性:
- RSA双向加密: (前端JS库-jsencrypt.js)
RSA 加密规则:公钥(publicKey)加密、私钥(privateKey)解密。不能逆向,私钥(privateKey) 加密、公钥(publicKey)解密。说白了就是前后端都需要用公钥(publicKey)进行加密,用私钥(privateKey)进行解密。
- 首先定义两对秘钥:秘钥对A、秘钥对B
- 前端保存 pubKeyA priKeyB, 后端保存 pubKeyB priKeyA
- 前端使用公钥A(publicA)对数据进行加密,后端通过公钥A(publicKeyA)对应的私钥A(privateKeyA)进行解密
- 后端使用公钥B(publicKeyB)进行加密,前端通过公钥B(publicKeyB)对应的私钥A(privateKeyA)进行解密。
- 虽然私钥(privateKeyB)和公钥(publicKeyA)都在前端代码中,但是这两个并不是一对,就算是全部拿到,也无法成功解密
- AES 对称加密 + 非对称加密 (参考https://www.zhiu.cn/148178.html)(前端js库:crypto-js, javascript-MD5.js)
为防止请求被阻拦后篡改 body,可在发请求时,将 body 字符串进行一个 md5 加密后在恳求头传输,服务器收到恳求后,解密 body 后再 md5 与恳求头的进行校验,可验证是否请求被篡改
三、 防篡改(url 防篡改---微信支付,支付宝支付)
- 数据签名,防止请求参数被篡改(参考https://blog.csdn.net/Weixiaohuai/article/details/106420234)
总结:
开放API安全性 方案一: 【ak/as(合法用户) + https(传输加密) + 数据签名防篡改(防篡改)】
方案二:【ak/as + RSA双向加密 + 数据签名】
方案三:【ak/as + AES 对称加密 / RSA非对称加密】