simker

Life is too short, just make it.


  • 首页

  • 归档

  • 分类

  • 标签

  • 关于

  • 音乐

  • 搜索

浅谈前后端请求加密与签名

发表于 2020-06-28 更新于 2021-04-27 分类于 PHP , JavaScript 阅读次数: Disqus:
本文字数: 2.1k 阅读时长 ≈ 2 分钟

最近在做服务请求加密相关的工作,于此记录下一些资料。

引言

网络中的请求安全问题一般有两个方面:

  • 请求安全性:即服务端收到你的请求时,需要鉴别请求是否有效
  • 数据保密性:请求数据可能会被抓包,为避免用户敏感数据被窃取,需要进行数据加密。

请求唯一性 - 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接口).

文章参考:

  • 网络请求中常见的加密机制和加密算法理解
Cai xian 微信支付

微信支付

Cai xian 支付宝

支付宝

# http # data # secret
使用JavaScript监听Dom节点变化
PHP基础笔记之类型
  • 文章目录
  • 站点概览
Cai xian

Cai xian

A super nice guy!
24 日志
12 分类
15 标签
  1. 1. 引言
  2. 2. 请求唯一性 - once, time|timestamp
  3. 3. 请求一致性|数据安全 - sign
  4. 4. 用户的身份认证 - token|Authorization
© 2019 – 2021 Cai xian | 70k | 1:04
由 Hexo 强力驱动 v3.9.0
|
主题 – NexT.Pisces v7.3.0
|