基于 HTTPS 对外提供 API,十万个为什么,求 web 安全高手指教

2020-01-15 22:05:23 +08:00
 phx13ye
对接过各种第三方,他们的 HTTPS 接口有时会要求
1 对数据计算签名,有 https 还有必要吗?
2 每次请求带上时间戳和 nonce,这个应该是防重放?
3 OAuth2 那一套 token 机制
4 稀奇古怪的数据加解密方式,主要是银行和支付公司

搞得我每次调试时都很郁闷

HTTPS 不是已经很完善了吗,上面四种哪些是瞎搞呢,应该做设计怎么做既可以简单实现,方便自己和他人调试,又足够安全呢?
5140 次点击
所在节点    程序员
24 条回复
unco020511
2020-01-16 11:30:11 +08:00
都有必要啊,签名是防篡改的,一般 :签名=不可逆算法(参数列表+时间戳+密钥)
phx13ye
2020-01-16 16:27:44 +08:00
@also24

要的是 『尽可能安全』
HTTPS 的服务端收到请求,加上这些验证,还有什么遗漏吗?
响应时,有什么措施是必须采纳的呢?
also24
2020-01-16 16:57:29 +08:00
@phx13ye #22
遗漏有很多种可能吧,我这二把刀应该保证不了没有遗漏。
这东西应该只涉及到你期望覆盖的面的大小,没有尽头。

比如说 客户端是否要对 https 证书进行强验证(不止验证证书有效性,还要验证证书是否一致)。
比如说 时间戳+签名 需要有时间差冗余,避免时间不一致导致出错,而冗余就带来了短时间内重放的风险,此时又需要缓存若干个请求信息来防止短时间内的重放。
比如说 你的 token 机制是否足够安全,是否有吊销机制( JWT 出来挨打)。

每个措施,一般都是对应某个场景给出的,其实还是确认场景的问题。



另外回应你附言中的问题:

content-type 是 json 的话,签名可以放进 header,也可以给 json 再罩一层 “非签名” 区域。
即:参与签名运算的只是某个子字段,而另一个子字段存储签名信息即可。

但是这里需要注意:
JSON 的 k-v 是无序的,且 JSON 序列化的格式是可以自定义的,当你期望对一个 JSON 求签名( hash )的时候,请务必协调好两端的 JSON 序列化格式及顺序。
如果觉得麻烦,也可以选择将需要传递的 JSON 对象,先序列化之后,存于某个 JSON String 字段。


> 对于请求,body 一般只能读取一次,读取时要先缓存一份,然后和请求首部比对
这段话我没有理解是什么意思,为什么只能读取一次。
可以考虑设置类似 “API 网关” 的概念,所有请求先经过网关的核验之后再传入业务代码。
phx13ye
2020-01-16 18:23:14 +08:00
@also24 感谢大佬

防重放准备这样做
1.验证签名防篡改
2.判断服务器时间是否比请求 timestamp
3.判断 nonce 是否 redis set 中

是考虑 json 的字段可以嵌套和 k-v 无序,才将整个 body hash😭

请求可以读取多次,只是很多时候 web 框架只让读取一次,可以缓存一份替代,在 java-spring 里是 ContentCachingRequestWrapper,在 go-gin 里是 ioutil.NopCloser

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

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

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

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

© 2021 V2EX