1
yin1999 2022-07-26 06:20:48 +08:00 via Android 2
不了解这个产品,就举个例子吧,有时需要在客户端调用这些 API ,但鉴权的 key 不能下发给客户端(比如网盘服务,需要由客户端向对象存储服务上传图片),可以由服务端生成签名后的 URL ,下发给客户端,客户端直接根据 URL 发送请求,即完成了一次 API 调用,但又不会泄漏 key 。
|
2
ZE3kr 2022-07-26 06:44:25 +08:00 via iPhone
除了一楼说的,也不排除一些开发者配置有问题导致不验证证书的情况,以及某些操作系统过于陈旧证书缺失导致开发者为了省事不验证证书。但不管怎样不验证证书都是非常不专业的做法。也有可能是历史遗留问题,该系统曾今是 HTTP 的,后来升级 HTTPS 了但接口没变
微信支付的 Native API 也这样搞…实际上用了 HTTPS 就不需要再一次加密了。估计是为了兼容 HTTP 系统吧 https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_5.shtml |
3
moen 2022-07-26 06:59:25 +08:00
HTTPS 防的是传输过程中不会被监听,但是不防中间人攻击
假如中间人能获取到发送者的公钥,那中间人就能解密并篡改请求,所以要用额外的私钥签名防止内容被篡改;但只有签名也不行,因为中间人可以选择不解密原文重发,所以还要加上时间戳并参与签名防止重放攻击 |
4
ZE3kr 2022-07-26 07:06:09 +08:00 via iPhone 2
HTTPS 当然可以防御中间人攻击 https://datatracker.ietf.org/doc/html/rfc2818#section-3.1
|
5
phpfpm 2022-07-26 07:26:29 +08:00 6
我觉得这是几个维度的事情
ssl 解决的是你们之间的通信是不是安全,和业务无关 Authentication ( AuthN )解决的是和你通信的是谁,毕竟不是想和每一个人打交道 Authorization ( AuthZ )解决的是确定对方身份之后,他能做什么 |
6
Daiwf 2022-07-26 08:41:15 +08:00
https 有单向认证和双向认证的 我们一般用的是单向认证不需要本地证书。只是证明网站是官方的。双向认证需要你自己有服务端证书同一个 root 签发的证书。这样就可以认证你。当然你讲的这种方案。是业务层的认证。又是另一个维度。
|
7
zed1018 2022-07-26 08:55:49 +08:00 5
因为国内的好多乐色项目,把 https 当成 zz 任务来完成,自签证书还不双向验证,不 pin ssl/HSTS 。所以只能多做一些脱裤子放屁的事情来显得自己的安全防护做到位了。
|
8
0o0O0o0O0o 2022-07-26 08:57:12 +08:00 via iPhone
|
9
oneisall8955 2022-07-26 09:07:11 +08:00 via Android
shopify 的 webhook 请求需要校验签名呢
|
10
wanguorui123 2022-07-26 09:12:13 +08:00
Pro 和 Pro Max 的区别
|
11
dzdh 2022-07-26 09:20:57 +08:00
好多回帖。就没人说说为啥列举的几个 server-side 的 api 他就是不用签名呢
|
12
aguesuka 2022-07-26 10:48:27 +08:00
虽然但是, 这个签名的功能和 https 没啥关系. appKey 是用户名, securetKey 是密码. 一般我们要登录拿到 session, 这个接口可以跳过登录.
|
13
aguesuka 2022-07-26 11:00:13 +08:00
github 用的是 Basic Authentication, 这个相当于密码明文传输, 而且每次携带密文. 尽管 https 下是安全的, 如果校验时间戳可以一定程度地防重攻击.
|
14
lululau 2022-07-26 11:04:38 +08:00 1
签名可以作为一种认证 (authentication) 的手段,除此之外,在 https 里又嵌一层签名的根本就不懂什么是签名什么是 https ,这种设计其实见得很多,很多金融相关的科技企业的产品都是瞎用加密技术的
|
15
aguesuka 2022-07-26 11:13:31 +08:00
不用 Basic Authentication 还是有意义的, 如果是服务器的 https 密钥泄露, 那么中间人最多只能看到明文. 如果是用户的密钥泄漏, 那只有当前用户受到影响. 相当于提高了鲁棒性.
|
16
seth19960929 2022-07-26 11:45:06 +08:00
都没说到点上. https 你被别人捉包了, 别人只是无法伪造数据, 可以无限请求.
比如说获取订单数据, 我现在获取 有 5 个订单, 一个小时后用户下单了, 我继续请求, 可以拿到 6 个订单了. 你用 sign, 你没发现 sign 参数基本都加了 ts 参数吗, 我服务端判断 ts 参数不在请求时间范围(比如说 5s 内的)直接不处理你的请求. 还有一些加了参数, 比如说你查询接口, 查询 手机, 你捉包之后可以随意查. 但是加 sign 参数, 我手机混入 sign, 你查电脑, sign 就会不一致. |
17
zed1018 2022-07-26 11:49:33 +08:00
@seth19960929 那五秒内呢
|
18
ZE3kr 2022-07-26 11:59:12 +08:00 via iPhone
@seth19960929 HTTPS 不可被重放攻击,不存在你说的无限请求
|
19
seth19960929 2022-07-26 12:03:04 +08:00 2
@zed1018 5 s 内的通过业务代码解决. 这是一个类似中间件的解决方案
@ZE3kr https://help.aliyun.com/document_detail/50041.html API 重放攻击( Replay Attacks )又称重播攻击、回放攻击,这种攻击会不断恶意或欺诈性地重复一个有效的 API 请求。攻击者利用网络监听或者其他方式盗取 API 请求,进行一定的处理后,再把它重新发给认证服务器,是黑客常用的攻击方式之一。 HTTPS 数据加密是否可以防止重放攻击? 否,加密可以有效防止明文数据被监听,但是却防止不了重放攻击。 |
20
ZE3kr 2022-07-26 12:06:11 +08:00 via iPhone
|
21
seth19960929 2022-07-26 12:24:26 +08:00
@zed1018 看了一下 5 内的常见解决方案, 上个 redis 或者用 bitmap, 缓存时间 >= 允许容错的时间.
|
22
seth19960929 2022-07-26 12:30:04 +08:00
@ZE3kr 感觉应该是理解上的问题, 让我问问阿里云
|
23
ZE3kr 2022-07-26 12:36:46 +08:00 via iPhone
@seth19960929 我查了下并不是所有版本 TLS 都可以防止重放。以及中间人可以干扰 HTTPS 连接导致客户端那边发多个 HTTP 内容相同但数据包不同的重试请求实现“重放”。不过不论哪种重放本来也需要业务上作处理,因为网络不稳定时客户端就可能重试请求
|
24
momocraft 2022-07-26 12:41:27 +08:00 1
要求 payload 里放一份自己发明的 json HMAC 的 大多是中国特产
我怀疑是刻舟求剑跟某几个大厂学的 |
25
libook 2022-07-26 12:46:03 +08:00
识别请求发起方的身份。比如我是一个攻击者,因为这个域的 CA 公钥是公开的,那么我完全可以发起一个跟合法用户一样加密的 HTTPS 请求。如果加上签名了,相当于服务器会对客户端的合法性进行验证,也就是说攻击者只要没法造出合法的签名,服务器就可以认定为非法请求。
你给出的 API 文档里说,你要在 map 序列化后拼接分配给你的 SK ,这个 SK 只有你和服务器知道,别人不知道,那么服务器就可以拿分配给你的 SK 做和你一样的操作就能得出相同的 MD5 ,就能证明请求是你发的,而不是其他人发的。 对于 HTTPS 来说,header 也是会被加密传输的,所以其实不是特别有必要将你的参数序列化一起签名。假设你签名不需要带着参数,一旦某一次的签名泄漏了,攻击者就可以拿着这个签名带着任何他想要的参数去发请求,服务器会误认为是你发的,所以带着参数一起签名可以在你签名泄漏过一次的时候,至少不会被别人伪造不同参数的请求。 签名的时候拼了时间戳,可以确保当签名泄漏一次后,在一定时间之外,攻击者无法使用相同参数来发起攻击。 |
26
dzdh 2022-07-26 12:50:04 +08:00
@seth19960929 #16
这场景都是 C->S 。那 S-S 呢。 C->S 自己实现一套 Sign 的意义呢。浏览器端 JS 公开的,sign 的 salt 哪里来呢。安卓端 Hook 之后一览无遗。图个啥呢。 |
28
ychost 2022-07-26 14:07:17 +08:00
AK/SK 和 Https 不冲突
|
29
seth19960929 2022-07-26 14:46:27 +08:00
|
30
andyskaura 2022-07-26 15:02:13 +08:00
就好比寄快递:
ssl:保证快递运输安全,不会被掉包偷盗。 key:快递员要求验证身份证,确保是本人收件。 |
31
jiulang 2022-07-26 16:28:24 +08:00 1
只有 https:直接放屁;
https+这个签名:先脱个裤子,再放个屁 |
32
jiulang 2022-07-26 16:31:56 +08:00 3
喜欢脱裤子放屁的人说:我脱了裤子再放,自我感觉卫生;
直接放屁的人说:方便还没啥问题,卫生不卫生看屁本身; |
33
dzdh 2022-07-26 17:47:16 +08:00
|
35
dzdh 2022-07-26 17:50:01 +08:00
@seth19960929 #29
太能了。客户端抓个包而已。 https://zhuanlan.zhihu.com/p/355450670 https://blog.csdn.net/qq_44862120/article/details/107467725 https://www.cnblogs.com/cherish-hao/p/12815603.html ios 越狱后照抓不误。函数 hook 完每一步干了啥都清清楚楚。S-S 服务端,没必要,可以客户端证书。C->S 端,更更没必要。 |
36
andyskaura 2022-07-26 17:56:27 +08:00
@dzdh 虽然 key 有那么一丁点保证安全的能力,但我更多的是把 key 理解为一个业务需求。
|
37
dzdh 2022-07-26 17:59:23 +08:00
@andyskaura yep
|
38
seth19960929 2022-07-26 18:20:54 +08:00
@dzdh 直接裸露的难度是几, 捉包的难度是几, 反编译找到 key 的难度是几.
|
39
seth19960929 2022-07-26 18:21:38 +08:00
按你这么这么说, 希望各个大厂 app 都不要加所谓保护机制了, 直接调就行了. 你去和他们说才管用.
|
40
dzdh 2022-07-26 18:24:14 +08:00
https://v2ex.com/help/api
包括 v2 的 api 也是 有个固定的 token 就行。我保护好我的 token 即可,泄露了就重新生成。Server-Server 的模式。 sign 私以为适合的是类似 S3 的私有文件开放给他人下载场景用,三方用户无需任何配置可直接凭 URL 访问资源。 |
41
dzdh 2022-07-26 18:27:16 +08:00
|
42
seth19960929 2022-07-26 18:38:25 +08:00
@dzdh S -> S 就不需要吗? 服务器被入侵了, 你的请求就不被捉了吗
|
43
seth19960929 2022-07-26 18:38:48 +08:00
直接用 appid + secretkey 和裸奔有什么区别
|
44
vantis 2022-07-26 18:45:38 +08:00
自签名还有一个功能 是证明调用方自己是合法的调用方
|
45
wanacry 2022-07-26 18:54:53 +08:00 via iPhone
之前也对接过这种 api ,一直都是照葫芦画瓢,也不懂哈哈
|
46
eason1874 2022-07-26 19:17:51 +08:00
参数签名可以确保,一旦请求泄露了,别人也构造不了新请求
在 HTTPS 可靠的情况,这个签名没意义,在 HTTPS 不一定可靠的情况就很有意义。比如内网有流量审计、代理上网的时候 |
47
dzdh 2022-07-26 20:25:33 +08:00
@seth19960929
#42 服务器都被入侵了你告诉我有什么手段还能是安全的?就算你硬件加密也屁用没有啊? #43 那 stripe\google\facebook\paypal 就都不安全呗? @vantis #44 不是光 https 就没别的了。https+ http basic auth 一样能证明啊 |
48
datoujiejie221 2022-07-26 20:47:14 +08:00 via iPhone
签名不是为了防监听的 是防止身份伪造的
这种方法在 openapi 很常见 比如云云对接时 a 厂商申请了好几个 appkey 那么 a 厂商是不是可以猜出规律来去暴力破解其他厂商的 key 呢 但是有了签名的保障 a 厂商很难猜出其他厂商的 key 和 secret 的 对于反编译的问题,最好还是服务器云云对接 openapi |
49
dzdh 2022-07-26 21:05:14 +08:00
@datoujiejie221
我有个疑问。用 hmac/md*/sha*(rsa 除外啊)我不是也可以无限尝试嘛? 因为你采用的哈希算法和排列方式是公开的呀。 无非是 https://xx?key=$RANDOM 无限 和 https://xx?{hmac(key1value1,key2value2,$RANDOM_SALT} 的问题吗? 如果是 rsasign ,那是不是一样可以客户端证书呢? |
50
datoujiejie221 2022-07-26 21:20:28 +08:00 via iPhone
@dzdh 所以 secret 生成的时候一定要足够随机
key 不能太随机主要还要考虑数据库索引性能 所以你看国内一些平台 key 或 appid 比较简单 但是 secret 很复杂 密码复杂了 暴力破解成本也很高呀 rsa 这种用在 jwt 这种场景是很很合适的 |
51
datoujiejie221 2022-07-26 21:33:05 +08:00 via iPhone
@dzdh rsasign 是签名方式 证书是连接建立握手的 只能说证书验证过程中用到了 rsa
|
52
dzdh 2022-07-26 22:07:16 +08:00
@datoujiejie221
不。我说的是 [客户端证书] 。必须是指定 CA 签发(私有)的证书,并且能被正确解析的从证书中解析出 COMMONNAME 当作 UID 使用的。 不是用于 HTTPS 连接的权威 CA 证书。 rsasign 指的是使用私有 RSA Private Key 对指定字符串生成的 sign 如( php: openssl_sign ($data, $private_key, $sign )) |
53
dorothyREN 2022-07-26 22:34:35 +08:00
@dzdh #40 你怎么知道已经泄漏了呢
|
54
dzdh 2022-07-26 22:45:02 +08:00
@dorothyREN #53 那签名怎么知道 secretkey 没泄漏呢
|
55
datoujiejie221 2022-07-26 23:02:23 +08:00 via iPhone
@dzdh 是的呀 那他也是连接建立的时候才验证呀 验证过了才会协商密钥 客户端证书又不是每次请求都验证
|
56
sivacohan 2022-07-26 23:09:44 +08:00
@seth19960929 在 19 楼说的大体是对的。
我认为楼主的问题是不明白为什么要有一个 sign 。 这个东西在没有 HTTPS 的时代,起到了一个防篡改的作用。 在有 HTTPS 的时代,HTTPS 保证了传输过程的安全性。但是客户端的安全性仍然存在风险,比如我可以打开 chrome 的 console ,然后复制出这个请求来进行重放。 这个 sign 不是 AAA ( authentication authorization and accounting )的范畴。 这个 sign 如果直接是通过 请求参数的 map + key 生成的,那就是保证数据可靠性,避免篡改。 这个 sign 如果是 请求参数 + salt ( timestamp ) + key 生成的,就除了数据可靠性之外,增加了一个防重放攻击的能力。 |
57
Chenhe 2022-07-27 09:09:43 +08:00 via Android
简单说。https 一般是验证服务器的身份。而这些 api 还需要验证客户端的身份。
|
58
siweipancc 2022-07-27 13:45:37 +08:00 via iPhone
……op 有什么服务是无偿提供的吗,我想用
|
59
siweipancc 2022-07-27 13:49:22 +08:00 via iPhone
@siweipancc 回个点子上的吧,这是保护买资源客户,甚至预防客户的熟人作案(这边发生过,然后还改造了一版)
|
60
EminemW 2022-07-27 23:53:49 +08:00
不就是用来校验用户是否合法的,很难理解吗
|
62
vantis 2022-07-29 09:11:13 +08:00
@dzdh 和服务器有啥关系……
HTTPS 是公开的证书 任何人都可以建立加密通信 但客户服务器怎么证明自己是自己呢?除非网站有一个客户服务器自己的证书并且对签名验签通过 这个就是签名的作用 签名的密钥是在之前记录进去的 只有你通过私有的密钥签名 服务器用你之前录入的公钥验签了 才能保证请求确实来自对应的客户服务器 以上和客户服务器被入侵是两个话题 如果你服务器被入侵了 是你自己持有的私钥泄漏了 这个服务器当然不知道访问者是攻击者的 |
63
dzdh 2022-07-29 09:17:16 +08:00
@vantis #62
首先回的是哪一楼啊 HTTPS 的证书是公开的,没错,在 TLS 握手阶段会发送给浏览器也没错。 然后呢?我 HTTPS 的基础之上,不使用 [签名] ,而使用 basic auth 就不能证明自己了吗? |
64
byte10 2022-08-14 23:14:12 +08:00
@datoujiejie221 我是好奇为啥大家聊偏了,就是一个鉴权的方案而已,不用签名,也可以换别的。。服了这些评论区。。。
|