一个关于请求与返回的数据加签的疑问

2019-12-16 17:51:39 +08:00
 x1aoYao

原始数据:

{ 
   "id":1,
   "info":{
      "name":"x",
      "age":19
   },
   "course":[
      "math"
   ],
   "timestamp":1575174600,
   "nonce":"xxx"
}

方案 1:

{
   "id":1,
   "info":{
      "name":"x",
      "age":19
   },
   "course":[
      "math"
   ],
   "timestamp":1575174600,
   "nonce":"xxx",
   "sign":"awoskedflvj"
}

方案 2:

{ 
   "data":{
      "id":1,
      "info":{
         "name":"x",
         "age":19
      },
      "course":[
         "math"
      ],
      "timestamp":1575174600,
      "nonce":"xxx"
   },
   "sign":"xcvoawierj"
}

我只用 golang 简单验证了这样不会出错,json.RawMessage 可以很好的解决。
想请问下这样做有什么问题没?如果方案 2 有问题,方案 1 在存在嵌套 json 的情况下也有问题。
为什么很多地方都采用先排序再拼接的方式呢,仅仅是数据来源可能在 header 里或者 url 里之类的情况吗?

或者有什么通用的比较好的解决方案

1895 次点击
所在节点    程序员
7 条回复
qiayue
2019-12-16 17:56:59 +08:00
排序的目的是尽量让每一次请求的签名都不一样
x1aoYao
2019-12-16 18:03:40 +08:00
@qiayue 参数中加 nonce 随机字符串才是为了让签名不一致吧
排序再拼接是为了排除 json 格式的影响吧
kkkkkrua
2019-12-16 18:11:14 +08:00
排序是为了消除一些传输中导致顺序更改的问题,你换成 json 的话,多一个空格你就验证不通过了
index90
2019-12-16 18:15:48 +08:00
为什么不把签名信息放在 header 中?
index90
2019-12-16 18:23:03 +08:00
排序再拼接,一般是用于 query 参数的处理,你无法确保 client 的签名是 key 的顺序与 server 签名时 key 的顺序一致,所以一般会约定先按 key 排序再签名
body 的参数不应该篡改,直接当做 byte 数组进行签名
签名信息一般放在 header 中直接提取,而不是像你例子中那样,需要反序列化之后才能提取,这样多浪费计算资源
x1aoYao
2019-12-16 18:33:31 +08:00
@kkkkkrua 所以需要加签验签的时候都把 json 都做 byte 数字
@index90 同意你的说法 body 就是整个 json,sign 放在 header
kkkkkrua
2019-12-16 18:37:35 +08:00
建议方案 1 的加密方式,sign 是否要放到 json 里,都可以,只要约定好就可以。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/629551

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX