关于 https 及接口安全性方面的几个问题

2021-11-24 10:50:54 +08:00
 unco020511

以下问题适用于服务端提供接口给自己客户端调用(客户端不限制浏览器 /app/小程序这些形式),从服务端接口设计角度出发

  1. https 已经足够安全,是否还需要加签 /验签
  2. OAuth2 据我所了解的是适用于临时给第三方授权数据访问权限的场景,那么 OAuth2 是否不适应于自身用户系统的权限控制场景?国内程序员有没有错误使用(或理解)OAuth2?
  3. 用户登录 /权限应该如何设计,比如基于 jwt?又或是 sessionId?或者自己签发 token,存储在数据中心(redis 之类),每次让前端带上 token,去数据中心查找验证?这些有什么本质区别,哪种好(从安全+易用角度同时考虑)
  4. 什么是 https 的双向验证,与标准 https 有啥区别(经常听到双向 https 验证这个词,一直不太明白)
  5. 内部设计的 api 文档让别人看到会有危险吗?客户端使用抓包工具 /浏览器 F12 都能看到 https 的数据,这为什么不涉及安全学问题

下面的问题基于服务端向第三方提供 openapi 场景(第三方可能在服务端发起,也可能在客户端发起,不受控制)

  1. https 已经足够安全,是否还需要加签 /验签.为什么国内类似支付宝支付 /微信支付 /银行聚合支付之类都需要加解密 /加签验签机制,是否过度设计
2838 次点击
所在节点    程序员
12 条回复
liuidetmks
2021-11-24 10:55:00 +08:00
https 只能防止中间人,不能防止用户恶意请求
加上验签还是有必要的,能显著增加破解成本,拦截绝大部分很多小白
mhycy
2021-11-24 10:56:31 +08:00
加签验签机制,本质上是个数据完整性校验机制,是安全机制的一环
HTTPS 谁都能发,但签你得挖清楚代码才能重新构造,成本不一样
而且加签本质上是数据完整性校验的一环,以验证数据是否完整 (虽说不一定合法)
0ZXYDDu796nVCFxq
2021-11-24 11:21:51 +08:00
1. 如果要防别人调用,加签是一个办法,起码提高调用的成本。
3. 权限设计是产品的问题。如果有多个业务线,去中心的验证比较好。
4. https 双向认证就是给客户端颁发证书,比较少用这种技术,可以参考 https://www.jianshu.com/p/2b2d1f511959
5. 客户端浏览器只能看到自己的数据。

支付和网银这些太重要了,仅依赖 CA 体系是不够的。
joyhub2140
2021-11-24 11:22:22 +08:00
https 只能保证通过信道里面的内容不会被第三者抓包读取,如果没有 CA 的存在,也防不了中间人伪装攻击。

客户端能看到数据,本质上已经不是 https 的锅了,因为 https 已经把数据安全地送到终端这边,终端喜欢怎么样处理就不是 https 协议能管的了。

https 本质上就是 结合非对称加密和对称加密算法和权威 CA 机构共同保证数据在“传输过程”不会泄露,不会被冒充身份,不会被非法修改。

其余的安全鉴权操作应该在 https 的上层处理了。
2i2Re2PLMaDnghL
2021-11-24 11:24:19 +08:00
1. 不是需要,而是可选的。即使是防止恶意请求也可以在 HTTP 基础上构建有状态的接口协议,不一定要用无状态的加签验签,实现上更方便就是对性能有压制。
2. OAuth/2 的设计目的是临时授权第三方,但同样可以用于自身权限。尤其是自身系统本身就是极度强调低耦合的情况下。不过实际上也有因为默认用户不是小白,所以让用户自己挑选权限生成所需 token 的系统,比如 Github 。
3. jwt 讨论很多,主要问题是难以撤回。我认为这是一种服务端在不可信的客户端存储关键信息的手段,它构成有用的前提是:a. 服务端自己不适合存储信息; b. 这些信息必只会在客户端访问时改变。session id 和你这里说的 token 只是名字的区别,全部归到 magic key 里面去。
4. SSL/TLS 可以存在客户端证书。不过一般不推荐,主要原因是它强制你需要动 session 层,而不是通常你会进行编程活动的 application 层。如果仅仅是验证还罢了,要用于区分身份意味着你需要大改 session 层。
5. 内部设计的 API 被暴露主要是抽象泄漏的问题。
3dwelcome
2021-11-24 11:29:52 +08:00
“什么是 https 的双向验证,与标准 https 有啥区别(经常听到双向 https 验证这个词,一直不太明白)”

微信支付就是 HTTPS 双向验证,因为官方服务器需要知道你这个客户端是真实有效的,需要有证书来证明自己身份,而不是随便哪个第三方客户端的伪造链接。
2i2Re2PLMaDnghL
2021-11-24 11:30:53 +08:00
第三方接口,如果涉及关键业务也会要求对参数整体进行签名,主要是为了避免搞砸的情况,比如过长的字符串发生了自动的截断。
你永远不会嫌安全措施太多,你只会嫌安全措施太贵。
非对称密钥为什么还要加 passphrase ?密码都这么长了为什么要 2FA ?
luoqeng
2021-11-24 11:33:07 +08:00
1. https 解决的是数据加密传输中间人攻击,加签 /验签是业务逻辑需要对接口确认调用者是否有权限。

2. 没看明白,权限是属于业务逻辑。

3. http 是无状态协议请求需要带上状态做鉴权,本质无差别。

4. 服务器验证客户端。

5. 看具体 API 设计,抓包不能解密 https 数据,除非有证书私钥,浏览器 F12 ,请求都是你自己浏览器发的为什么不能看? https 解决的是你不能看别人发的请求。


加签 /验签 主要是做开发 API 鉴权,是那个开发者调用了 API ,仿制任意人调用。HTTPS 解决数据加密传输,传输过程中不被篡改。
wy315700
2021-11-24 11:34:27 +08:00
OAuth2 常用于社交场景,用于授权第三方用户登录本系统,经常被用于授权本系统用户登录第三方,算是一种不恰当的使用吧。
内部系统授权请使用 cas (对称加密)或者 saml (非对称加密)协议


https 不够安全。不安全的地方在于 ca ,而不是 https 协议本身。只要有一个被控制的 CA ,都能劫持数据。除非程序里绑定 CA
FakNoCNName
2021-11-24 11:41:05 +08:00
不一样,ssl 加密是保证的传输通道安全,数据校验保证的是数据(本身的)一致性(收发的数据一致,数据和预期的也一致)。所以也就可以通过数据校验来判断数据是否有效、是否重复等等,这些有可以用在安全方面。
libook
2021-11-24 12:00:34 +08:00
当我们讨论“安全”的时候,应该讨论具体问题,或者说“希望防止什么安全问题的发生”。

HTTPS 的“安全”基本指的是点对点加密安全,防止数据发出后被其他人拦截获取到内容。另外 HTTPS 还能在一定程度上起到间接识别数据接收方的作用,因为仅有真实的接收方有私钥,只要你用可靠的公钥加密数据,也就只有真实的接收方可以解密数据。

除此之外的安全问题,可能都无法靠 HTTPS 来解决。

回到题主的问题:

1. HTTPS 解决的安全问题和签名、验签解决的安全问题不是同一类问题,签名、验签通常是用来让接收方识别发送方的身份(你是谁),也就是防止其他人冒充身份发送方给接收方发送信息,这需要发送方将公钥保密,而 HTTPS 通常使用公开的公钥,所以接收方通常信任所有使用公开公钥的发送方(私签证书的场景除外)。

2. 大多自有系统内的身份鉴别是客户-服务的双方场景,所以身份鉴别机制可以设计得简单一些; OAuth2 是针对三方场景进行设计的,即第三方身份鉴别服务-服务-用户,自有系统也不是不能用,只不过多数情况下没必要。

3. 这些都是最细粒度的工具,可以被用来做各种用户会话机制的设计。用户会话机制按照将会话信息存储的位置可以大体分为客户端存储和服务端存储两类;服务端存储就是客户端仅保存一个 ID ,客户端发请求到服务端的时候携带这个 ID ,服务端根据 ID 查找到会话信息,再判断用户是否有权限进行操作;客户端存储就是将会话信息进行加密存储在客户端上,客户端每次请求服务端都携带这个密文,服务端解密密文再判断用户是否有权限进行操作。服务端存储的好处是支持服务端自主踢掉用户的会话,缺点就是占用服务端存储空间,且对于分布式服务来说需要确保各节点处理会话信息的一致性;客户端储存的优点相反。当然架构设计都不是绝对的,也有混合方案,要看实际需求。

4. 简单理解就是 HTTPS 单项认证会让客户端验证服务端的合法性,双向认证就是在此基础上服务端也会验证客户端的合法性,跟签名、验签不同的是,这种验证不会关心“你是谁”。

5. 抓包仅能看到 API 的表征,但看不到具体含义,比如我传餐 a=1&b=2&c=3 ,没有文档你很难知道 a 、b 、c 都代表什么意思,取值范围是什么,对于 API 的设计者来说,可以使用易于理解的参数命名方式(如 name 、password ),也可以用不易于理解的命名方式,使得搞破坏的成本大大增加。所以 API 文档能不能公开,得看具体情况。

最后一个问题,签名、验签的作用我上面都说了,所以不算过度设计,HTTPS 基础上再加加解密可以进一步提升遭到攻击的难度,可以防范如客户端被安装了恶意证书的极端情况。
eason1874
2021-11-24 12:48:56 +08:00
一、为什么有 HTTPS 还要另外签名

1 、确确保参数完整传递,没有截断、转义之类的问题;
2 、防止因 URL 泄露导致的安全问题;在浏览器历史记录、代理自动配置 PAC 、网络流量审计(包括服务商自己的前端服务器)等场景,URL 可能被记录,如果密钥就在 URL 里,会存在重放、非法构造新请求等隐患;签名就不会有这个问题,密钥不会离开代码环境,签名链接只能用一次。

二、OAuth2 的应用场景是:允许自己的用户授权给第三方读取用户资料,但又不希望第三方拿到用户的账户、密码,这样就可以按 OAuth2 标准建立一个开放授权流程,用户在自己的网站登录,授权时通过 OAuth2 建立一个令牌发给第三方,第三方拿着这个令牌来读取资料。内部授权一般不搞这么复杂,除非产品线是互相独立的。

三、Session ID 和 Token 基本没区别。JWT 的区别是,JWT 带签名,前端服务器不用查后端 API 就能判断这是不是你们签发的令牌,非法构造的和过期的不用到后端验证就能给拒绝掉。普通 Token 没签名,只要格式对了,不查后端你分不清这是不是你签发的。

四、常规 HTTPS 是用户单向认证服务器,服务器不管用户是谁,匿名用户也建立通信。双向认证是服务器也要求验证用户,用户必须使用服务器签发、认可的证书来建立通信,证书不对的就拒绝。

五、私有 API 和公共 API 一样安全靠鉴权机制。但文档有利于理解和构造 API 请求,对调用方来说,有文档省很多事,可以说保护好私有 API 文档可以增加额外的安全性。

中间人抓包为什么不涉及安全学问题,涉及啊,HTTPS 就是为它而生的。按 F12 可以看到请求,因为 Web 设计思想就是开放,互联互通,不搞黑箱,用户有权知道自己在访问什么站点。

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

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

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

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

© 2021 V2EX