今天看到百川大模型的接口文档 https://platform.baichuan-ai.com/docs/api 中要求对请求内容和时间戳进行签名,想到前几天在 V2EX 看到的帖子吐槽腾讯大模型 API 的签名( https://v2ex.com/t/975832 )。
而我们去看 OpenAI 等公司提供的 API ,是不需要这种签名的。
所以想讨论一下,在 HTTPS 时代这种签名是否还有必要?还是一种思维惯性?
我的理解:在 HTTPS 之前,这样的签名可以有效防止请求内容被篡改,是很有必要的,但现在 HTTPS 普及了,这里的好处并不存在了。另一点是重放攻击,我了解不多,请懂的朋友讲讲。
1
wudaye 2023-09-25 19:27:54 +08:00 via Android
好问题。我能想到的一点是,万一被侵入内网了呢
|
2
julyclyde 2023-09-25 19:40:13 +08:00 2
双向证书 https 的话,我觉得不需要
|
3
momocraft 2023-09-25 19:40:42 +08:00
刻舟求剑
|
4
ospider 2023-09-25 19:45:21 +08:00
惯性思维,鉴定完毕。现在签名唯一的作用是反爬,自己提供的 API 还签名,纯属脱裤子放屁
|
8
1423 2023-09-25 19:52:23 +08:00
apikey 是与预共享的
非对称可以避免抵赖 |
10
tool2d 2023-09-25 19:54:30 +08:00
"但现在 HTTPS 普及了,这里的好处并不存在了。"
需要 SSL pin 才能确保证书不是中间人的。现在 root 后的安卓手机,挂一个自签 CA 证书,实在太方便了。 |
12
xmumiffy 2023-09-25 20:15:34 +08:00 1
确实没有必要,但国内主流都这么做,你不这么做就要解释为什么不这么做,教他们为什么 HTTPS 是足够安全的。
天天解释累了,就加上了 |
13
ysc3839 2023-09-25 20:16:33 +08:00 via Android 2
个人印象中签名更多是防第三方客户端,把签名的 key 各种加密混淆藏起来,让你抓到包了也没法直接调用,得花时间找 key 。除此之外似乎就只有防重放攻击了。
其实签名的 key 就是预共享密钥(PSK)了,配合 http 使用时完全可以把所有数据都加密。 |
14
leonshaw 2023-09-25 20:28:23 +08:00
认证用吧,没有 SSL pin 请求里直接放 secret 可能被中间人。
|
15
euph 2023-09-25 20:41:19 +08:00 via Android
我也觉得没必要签名,不然我抓包都没意思了
|
16
tool2d 2023-09-25 20:58:48 +08:00
@cheetah "这些 API 也不是给客户端环境调用的呀,是服务端调用的"
我一直是客户端调用的,当然我是自己用,不怕 api key 外泄。 如果是服务器之间通讯,似乎确实没太大必要。就一个 MD5 ,就算有中间人,人家也随手给加上了。 难是难在未知 KEY 的加密签名,比如 HMAC 签名,至少能防一部分恶意请求。 |
17
walpurgis 2023-09-25 21:01:52 +08:00 3
没必要,国内搞签名跟万年 java8 有异曲同工之妙,很多技术决策者的思想已经僵化了,举例子 OAuth1.0 标准是要求签名的,2.0 标准要求 HTTPS 后就去掉了签名
非 public api 防爬虫防抓包啥的,其实是把签名当成加密来使用了,直接套一层 aes 效果更好也更简单 |
18
rocmax 2023-09-25 21:13:41 +08:00 via Android
@xmumiffy 同感,跟别人解释过这个问题,对方没话说了就是一句万一 ssl 有漏洞呢。我心说能攻破 ssl 的人看得上你这点破数据吗?
|
19
gadfly3173 2023-09-25 21:23:06 +08:00 via Android 2
微信支付的回调 api 是有独立证书的加密和验签的,这样可以保证你收到的支付成功回调是微信发出的而不是伪造的(因为你的回调接口在公网,如果这个地址泄露了别人就可以伪造支付成功请求给你了)。这种客户端调服务商的接口确实没什么必要,毕竟你的 access token 泄露了也不耽误服务商赚钱,只能说是防傻子的一道保险
|
20
Bingchunmoli 2023-09-25 21:40:39 +08:00 via Android
@rocmax 并不是攻破,而是拒绝 https 又提供 http 服务,国内很多都是同时支持 http 和 https 的
|
21
rocmax 2023-09-25 22:02:48 +08:00 via Android
@Bingchunmoli 现在讨论的不就是用 https 的前提下 api 签名还有没有必要吗?
|
22
GeruzoniAnsasu 2023-09-25 22:11:29 +08:00
|
23
huangzhiyia 2023-09-25 22:27:12 +08:00 via Android
GitHub Access Token
AWS Access & Access Secret 等等,看场景。 |
24
adoal 2023-09-25 23:13:36 +08:00
日经日读,月经月诵
|
25
maocat 2023-09-25 23:20:49 +08:00
国内基本都是 app_id+secret
很多三方 api 测试环境都是不带 https |
26
musi 2023-09-26 07:24:15 +08:00 via iPhone
@GeruzoniAnsasu 你现在是 V2EX 论坛,现在有人请求 A 用户的数据,你需不需要确认请求者就是 A ,如何保证?
|
27
mmdsun 2023-09-26 07:57:22 +08:00 via iPhone 1
这两个东西完全不一样好吧。
https 不防客户端自己抓包解数据,签名一定程度防这点。 https 再厉害也是防止其他人截获数据,对客户端安装本地证书解密防御为 0 。 Chatgpt 官网你 F12 看看能不能找到接口调用,就知道有没有签名了 |
28
rocmax 2023-09-26 09:52:04 +08:00 1
@mmdsun 身份凭证在客户手里,想通过在客户端搞一些加密来防客户作恶是不可能实现的。所谓的“一定程度”防只是防君子不防小人,app 可以反编译,web 里脚本明摆着。
Chatgpt 怎么没有接口调用,返回内容是通过 Server-Sent Events 传的,身份认证用的是 JWT |
29
unco020511 2023-09-26 10:15:53 +08:00
我的理解是不需要的,都 https 了,为啥还需要额外加签验签?
|
31
hanyuwei70 2023-09-26 10:43:10 +08:00
LZ 可以去看一下 ACME 里面关于请求签名的部分,可能会有一些全新的看法
|
33
cheetah OP @hanyuwei70 可以简单讲讲嘛
|
36
Nazz 2023-09-26 11:25:22 +08:00
如果我用 charles 抓包改请求/响应参数, 阁下如何应对
|
38
chf007 2023-09-26 12:31:38 +08:00
肯定还是需要的。
用了 HTTPS 难道就不需要登录验证身份了么 |
40
GeruzoniAnsasu 2023-09-26 13:11:07 +08:00
@musi 我通过一个*SRF 漏洞修改你的账号发言权重
|
41
GeruzoniAnsasu 2023-09-26 13:17:00 +08:00
其实对请求签名防范的最核心问题是,你有些时候并不能保证请求内容和 token 来自同一可信源。举个底层逻辑相同但作用和机制完全不同的例子:CSRF token. 为什么明明用户都已经登录了,请求者拥有该用户的一切身份证明,为什么服务器还是不能完全信任这个请求?就因为服务器不能确定用户提供的身份证明能否证明他发起过请求内容。而通过下发 csrf token ,可以保证持有 session 凭证的所有者才能发起合法请求,这就能确认身份证明与请求内容是同一人发出的。
签名同理。 |
42
chf007 2023-09-26 13:30:08 +08:00
@cheetah
这里讨论的签名一般就用的 2 种场景下: 第一种:普通用户用浏览器等客户端调服务端接口要加签名,这种应该就是大家说的现在没必要的那种。因为大部分系统一般都是要登录的,调接口已经有了登录 token ,验证身份的问题就已经解决了。有的还要额外加签名,这种比较多的是金融类的公司,要求比较严格,为了防止中间人攻击什么的要加。然后有些普通公司可能是学到了也要加。这种在 HTTPS 下加不加呢,见仁见智,不做讨论。 第二种:在自已服务器端调腾讯混元大模型接口这种要加签名,这种肯定是要加的。因为腾讯云就给你了一个 appid 和 appkey (可能给的不止这些,其他 secretId 、secretKey 同理),然后有人要调腾讯云的接口,为了计费之类的,他得要知道你是谁,所以你要传 appid ,他才能算到你头上,但是 appid 又是公开的,要是你随便传了其他人的 appid 怎么办,所以就要你用不公开的 appkey 对参数进行签名,腾讯云收到后用只有你们俩知道的 appkey 对签名进行校验,如果一致,就说明你是真的 appid 所有人,这不就是验证身份么。 至说你说的 OpenAI 公司没有签名,得要看是客户端 API ,还是服务端 API ,服务端 API 一定是要有签名的,可能它 SDK 已经封装好了,可以抓包看看有没有,如果没有那一定有问题。 |
44
musi 2023-09-26 13:35:49 +08:00
@GeruzoniAnsasu #41 签名可不同理,签名的算法多样,参数也多样,不是所有系统的签名都包含随机戳,拿签名当 CSRF token 用并不可行
|
45
cheetah OP @GeruzoniAnsasu 请不要这样类比,不是一种东西。咱们就事论事。
|
46
cheetah OP @chf007 你也说了是服务器端调用,然后又说 appid 又是公开的,这不是自相矛盾么。另一方面,为什么一定要有 appid+appsecret 呢?只有一个 api key 不行吗?
OpenAI 的文档在这里,肯定是没有签名的: https://platform.openai.com/docs/api-reference/authentication |
47
cheetah OP @chf007 #42 另外也可以看看 GitHub 的文档 https://docs.github.com/en/rest/overview/authenticating-to-the-rest-api?apiVersion=2022-11-28 也是只有一个 key 放在 header 就可以的
|
48
astkaasa 2023-09-26 15:50:10 +08:00
@cheetah Remember that your API key is a secret! Do not share it with others or expose it in any client-side code (browsers, apps)
|
50
erikk0 2023-09-26 16:38:53 +08:00 via iPhone
要加的。主要是为了防止一些不懂装懂的专家和相关人员没事找事制造内卷和 KPI 。
|
52
julyclyde 2023-09-26 16:47:36 +08:00
@GeruzoniAnsasu 如果请求者有 A 的签名,我就“认为是 A”
至于到底是不是,那无所谓 |
53
iyaozhen 2023-09-26 16:51:10 +08:00
需要,现在证书一般都是单向,还是可以中间人抓包,改请求的。加签能防止重放攻击类的
|
55
gps949 2023-09-26 17:01:57 +08:00
抗抵赖。
事中确权,作为识别真实性的依据(如果你说的是 HTTPS 是双向的话,可以考虑不需要) 事后追责,作为日志完整性的记录。 |
56
xiqishow 2023-09-26 17:23:43 +08:00
如果使用单向 HTTPS 别说签名了,把请求/响应都用 AES 、SM 加密 仍然可以破解、仿造请求,比如你看看 bj301 的请求。
所以重要的是不要迷信单一的安全选项,尤其是 HTTPS 签名+时间戳还是能滤掉很多重放攻击,参数更改的,不能说完全没有意义 |
57
gadfly3173 2023-09-26 17:25:15 +08:00 via Android
@cheetah appid+appsecret 和单 token 是两种鉴权方式,对于不会有回调场景的应用来说,单 token 确实足够了,但是对于有回调场景(比如微信支付,题中这个大模型我没用过不知道),回调的时候就可以让业务系统根据 appid 来判断属于哪个商户/公众号,这样可以减轻业务系统的开发难度,可以直接在提供的回调接口的路径上写上 appid 来根据 pathVariable 判断。
回到你举例的文档和前面提到的 appid ,appid 的设计就是可以公开的,每个应用唯一的 id ,而单 token 模式下就没有这个可以区分的唯一标识了,使用哪种鉴权方式取决于产品的要求。 |
58
gadfly3173 2023-09-26 17:28:06 +08:00 via Android
@gadfly3173 接上文,微信中的 appid 和 mchid 的设计使得公众号可以嵌入指定的小程序,可以绑定不在同一个主体下的商户,也可以使得一个商户可以绑定对个公众号。在这上面的绑定过程中,appid/mchid 就是绑定的标识,而不是根据主体名称/公众号名称之类的信息
|
59
cheetah OP @gadfly3173 #57 额如果是回调区分业务的话,完全可以在业务层面实现啊。这跟签名毫无关系。按我的理解,appid+appsecret 是 oauth 的产物
|
60
jianyang 2023-09-26 17:32:10 +08:00
私有接口很有必要、一定程度防止爬虫等
公开接口一个鉴权 token 就行了、其他多余校验、纯属麻烦自己麻烦别人 |
61
Soler 2023-09-26 17:39:31 +08:00
哪有什么绝对的安全,如果是再用一些不常用的方式提供 API 接口调用,还不是项目经理在装 X ?
|
62
gadfly3173 2023-09-26 17:45:03 +08:00 via Android
@cheetah 是的,和签名没关系,只是产品层面是否公开 appid 的区别。我猜这个大模型用签名是公司上游中间件只支持了签名的模式,没有支持单 token 的授权模式,在他这个场景签名确实没有必要
|
63
zpf124 2023-09-26 17:46:31 +08:00
现在签名主要也就是防重放和随意修改链接参数了。
|
64
iugo 2023-09-26 17:53:47 +08:00
就事论事, 签名只能防止数据被修改, 不能防止中间人看数据. 和 HTTPS 解决的部分问题是一样, 但 HTTPS 做了更多.
那么强调签名必要性的愿意就只有一个了, 不信任 HTTPS. 不信任 HTTPS 机制, 那就真是大牛. 如果信任 HTTPS 机制但还是不信任 HTTPS, 那就是不信任 CA. CA 被攻破的概率不是没有, 但我觉得绝大多数人应该是信任 CA 的. |
65
liuidetmks 2023-09-26 17:56:36 +08:00
国内营商环境环境,你接口不做校验防御,能刷死你
https 只能防止第三方中间人,不能防止别有用心的用户。 跳过 SSL PIN 的方法,太通用了,随便搜下就有方法 内置白盒加密算法 + 代码混淆 能挡住 90%的人,起码破解没那么容易。 如果是对公的 api ,我记得阿里一些接口是直接给白盒 sdk ,accesskey 是不在代码里面的 |
66
jiangzm 2023-09-26 18:04:49 +08:00
测重点不一样,
HTTPS 保证的事传输安全 接口签名保证的是客户端身份和请求有效性 |
67
pkoukk 2023-09-26 18:14:05 +08:00
Public API 还非要加,有时候也不是后端的要求
可能公司的对外统一网关就是这个要求 |
68
rekulas 2023-09-26 18:17:51 +08:00
综合来说 目前各大平台的签名主要保证了防重放防修改和不暴露 key 的情况下进行鉴权,跟 https 还是不重叠的,所以加了安全性还是会提高一些(当然我还是喜欢 key 放 header 一把梭的接口。。)
@iugo 也可以防中间人的,有些服务用的非对称通信,反正越搞越麻烦了 |
69
CRUD 2023-09-26 18:18:11 +08:00
服务器对服务器单向调用的情况下,我觉得签名确实没必要,一个 token (或者叫 apiKey secret 之类的)可以识别当前请求者是谁就行了,这种情况下,加上 https 单向认证,以及 TLS 中本身包含的序号和时间戳可以防止请求重放,从网络层面,以我的见识想不到什么攻击的地方。
上面几个楼层说的签名也确实有其应用场景,但不是楼主想问的场景。 |
71
wy315700 2023-09-26 18:32:13 +08:00 5
一个是传输层安全
一个是应用层安全 根本不同的应用场景 大部分服务器架构都是用负载均衡承接 SSL ,进了内网就都是明文了。所以有些应用层会单独加一个安全校验。因为他不能保证外部请求被通过 SSL 来调用。 |
72
LLaMA2 2023-09-26 18:40:29 +08:00
1.有些项目部署的时候可能会让 https 的服务器证书前置化,在防火墙层就已经解密了数据了,然后后端都是 http 的,这时候业务部门不希望关键的数据被网络运维部门的人知道,避免不必要的隐患。
2.重放攻击 3.相关法规硬性要求。 总之 HTTPS 保障传输中不被中间人窃取 签名是保证增加一些篡改和窃取的难度 |
73
hsymlg 2023-09-26 19:08:43 +08:00
抓包改请求,防重放用的,和 https 我只能说有交集但是不多。
|
74
kingfalse 2023-09-26 19:20:08 +08:00 via Android
楼主这是没被爬虫毒打过。
|
75
flyqie 2023-09-26 19:20:14 +08:00
我这边有个场景,不知道是不是跟楼主说的是类似的玩意。
后端需要给前端返回一个带 sign 的 wss 地址,前端连接该地址实现 sdp 的实时交换。 |
76
Huelse 2023-09-26 19:31:39 +08:00 1
其实就是相当一部分人不能理解浏览器控制台能看到所有明文数据是正常的,然后疑问这也能算加密?
殊不知整个浏览器包括他所看到的内容都是客户端的一部分,能看到明文是理所当然的。 再深入就是内存安全和操作系统安全了,但说这些他们又不懂了,还是所看即所得的思维。 |
77
Bingchunmoli 2023-09-26 19:52:30 +08:00 via Android
@rocmax 但是实际情况并不是 hsts 情况,
|
78
ShuWei 2023-09-26 20:23:55 +08:00
up 说的是那种对请求内容进行计算得到一个哈希串的方式吧,其实必要性真的几乎没有,不过目前国内互联网好像流传着 https 也并不安全的思想,虽然我也不知道这个思想是怎么流传起来的
|
79
zhleonix 2023-09-26 21:04:05 +08:00
本地给你来个企业根证书就能绕过 https 了。
|
83
cheetah OP @wy315700 “一个是传输层安全,一个是应用层安全,根本不同的应用场景” 不等于应用层要把传输层已经解决的安全问题再解决一遍呀。你后面举得那个例子倒是有些道理的。
|
84
rekulas 2023-09-26 22:37:41 +08:00
|
85
nicoljiang 2023-09-27 02:03:20 +08:00
《在 HTTPS 时代对请求进行签名是否还有必要?》
|
86
nicoljiang 2023-09-27 02:08:50 +08:00
如果不加上这些你回复里才提到的“一些前提”,单就这标题,你自己觉得没必要吗?
|
88
j8sec 2023-09-27 02:53:52 +08:00
回答下答主的问题:
**使用了 HTTPS** 只是保护了用户的数据:这种情况可以防止黑客在网络层(包括公网、内网)截取或者串改数据。 **请求签名** 通常会结合 HTTPS 使用。我们假设一种情况,如果用户本身是个黑客、攻击者,怎么防止(或者加大成本)黑客的请求篡改攻击行为?请求签名+加密就由此而生,加密请求后,如果是 Web 、安卓环境通常还需要对代码混淆、加壳,加大反编译破解成本。当然,这种操作无法杜绝攻击行为,但可以让过去几秒钟的攻击成本提升至数小时(高手),甚至数天,让攻击者的篡改得不尝失. 国产厂商还在考虑通过签名来防止篡改;而 Apple 和 Windows 在新版本终端硬件要求厂家提供 TPM 模块,提供硬件可信;同时 Google 已经考虑在 Chrome 加入网页可信验证功能了[1],尝试从系统、浏览器底层杜绝请求篡改. - [1]. Web Environment Integrity(网页可信环境 API) https://github.com/RupertBenWiser/Web-Environment-Integrity/blob/main/explainer.md |
89
Masoud2023 2023-09-27 09:32:17 +08:00
我最开始也有一样的问题,我记得我甚至还发过差不多的帖子。
其实本质上这个东西依然存在的意义就是为了防止请求重放,也有可能靠那个 sign 再做一个幂等之类的。 |
90
CRUD 2023-09-27 09:41:09 +08:00
@rekulas #84 TLS 中,会对每次请求发送的数据进行 MAC 计算,MAC 算法的输入包括 数据 + 序号 + MAC 密钥,也就是说你想将某次请求的序号+1 然后进行重放的话,除了修改序号,还需要知道在握手协商环节所生成的密钥值,重新进行 MAC 计算才行。
[HTTPS 到底有多复杂,能防止重放攻击吗?]( https://zhuanlan.zhihu.com/p/360782536) |
91
xmumiffy 2023-09-27 10:10:24 +08:00
真有问题 Google API 早就被攻陷了,都用了十几年了,等不着现在我们来讨论.
|
92
liu938651469 2023-09-27 10:18:00 +08:00
GPT:在 HTTPS 时代,对请求进行签名的必要性取决于具体的使用情境和安全需求。HTTPS 提供了数据传输的加密和身份验证,它使用了公开密钥基础设施( PKI )来确保通信的机密性和完整性。但是,仍然有一些情况下,对请求进行签名可能仍然有必要:
1. **身份验证的强度**:HTTPS 可以确保通信双方的身份,但它可能无法确保请求的发出者就是合法的用户或应用程序。对请求进行签名可以增加对请求方身份的额外验证层级。 2. **完整性保护**:虽然 HTTPS 可以确保数据在传输过程中不被篡改,但它不一定能够确保请求的完整性。如果攻击者能够截获并篡改请求,签名可以用于验证请求是否在传输过程中被篡改。 3. **非 HTTPS 环境**:并非所有的通信都在安全的 HTTPS 环境下进行。在一些非 HTTPS 环境中,如局域网内部通信或内部系统之间的通信,对请求进行签名可以增加安全性。 4. **防止重放攻击**:签名可以用于防止重放攻击,攻击者可能会记录并再次发送有效请求,以欺骗服务器执行不必要的操作。签名可以包括时间戳等信息,以确保请求不会被重复执行。 5. **附加授权信息**:签名可以包括授权信息,以指定请求的权限和访问级别。这有助于服务器在处理请求时更精确地确定用户或应用程序的权限。 需要注意的是,对请求进行签名也会增加复杂性和计算成本。因此,在决定是否对请求进行签名时,需要综合考虑安全需求、性能和开发成本等因素。如果 HTTPS 提供的安全性足够满足您的需求,那么额外的请求签名可能并不是必要的。但对于某些高度敏感的应用程序或特定的使用情境,请求签名可能是一个有价值的安全增强措施。 |
93
fengpan567 2023-09-27 10:27:28 +08:00
secret 又不是只做签名校验,里面可能还包含了时间戳和身份证信息,防内鬼还是很有必要的
|
94
FrankAdler 2023-09-27 10:31:27 +08:00 via Android
有些请求是有实效性要求的,比如监测性的上报,或者需要计费,加上时间戳签名以及校验是有必要的,可能部分细分场景没必要,但是加上夜无伤大雅
|
95
realpg 2023-09-27 10:41:35 +08:00
@cheetah #46
我直接暴力破解 api key 阁下又当如何应对? 比如我知道 api key 是个 32 位 16 进制字符串,我直接暴力扫描,哪个能返回正确的 api ,说明这个 api key 是有效的。 我可能控制一大堆肉鸡去扫,万一扫到了你的,你突然发现腾讯给你的账单多了多了五百万元 你跟腾讯说你没调用五百亿次,腾讯说我这边记录调用就是五百亿次 你跟腾讯说凭啥说我调用了五百亿次 腾讯说就是五百亿次 你问腾讯 他冒充我调用凭啥? 腾讯说,凭他有你的 app secret 啊!欸不对,我怎么把 app secret 删了 那好吧 给你免了五百万 |
97
cheetah OP @realpg 这个场景下签名无效。另外你有没有算过这个数量级啊,如果真可行 OpenAI 早破产了。
|
98
Breacher 2023-09-27 11:07:04 +08:00 via iPhone 3
最近在接 Stripe 的核心 API ,它的商业模式比腾讯更加复杂重要,也没有用稀奇古怪的签名。使用 HTTPS ,接口交互的流程最重要就是保护好 API key ,而不是做无用的签名,你的签名泄漏是别人自然能够循着签名文档造出一个合法的签名来。
|
99
LynFt 2023-09-27 11:16:31 +08:00
当然有必要,可以理解为君子锁,小偷去偷自行车一扛就走,那卖自行车锁的难道都是智商税?签名的目的不是防止攻击,而是提高攻击的难度
|