在 HTTPS 时代对请求进行签名是否还有必要?

2023-09-25 19:21:43 +08:00
 cheetah

今天看到百川大模型的接口文档 https://platform.baichuan-ai.com/docs/api 中要求对请求内容和时间戳进行签名,想到前几天在 V2EX 看到的帖子吐槽腾讯大模型 API 的签名( https://v2ex.com/t/975832 )。

而我们去看 OpenAI 等公司提供的 API ,是不需要这种签名的。

所以想讨论一下,在 HTTPS 时代这种签名是否还有必要?还是一种思维惯性?

我的理解:在 HTTPS 之前,这样的签名可以有效防止请求内容被篡改,是很有必要的,但现在 HTTPS 普及了,这里的好处并不存在了。另一点是重放攻击,我了解不多,请懂的朋友讲讲。

9418 次点击
所在节点    程序员
135 条回复
GeruzoniAnsasu
2023-09-26 13:17:00 +08:00
其实对请求签名防范的最核心问题是,你有些时候并不能保证请求内容和 token 来自同一可信源。举个底层逻辑相同但作用和机制完全不同的例子:CSRF token. 为什么明明用户都已经登录了,请求者拥有该用户的一切身份证明,为什么服务器还是不能完全信任这个请求?就因为服务器不能确定用户提供的身份证明能否证明他发起过请求内容。而通过下发 csrf token ,可以保证持有 session 凭证的所有者才能发起合法请求,这就能确认身份证明与请求内容是同一人发出的。


签名同理。
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 已经封装好了,可以抓包看看有没有,如果没有那一定有问题。
Nazz
2023-09-26 13:35:22 +08:00
@cheetah 就是抓自己的包. 如果后端没有完善的权限校验逻辑, 可以改参数绕过一些前端的限制.
musi
2023-09-26 13:35:49 +08:00
@GeruzoniAnsasu #41 签名可不同理,签名的算法多样,参数也多样,不是所有系统的签名都包含随机戳,拿签名当 CSRF token 用并不可行
cheetah
2023-09-26 14:10:03 +08:00
@GeruzoniAnsasu 请不要这样类比,不是一种东西。咱们就事论事。
cheetah
2023-09-26 14:13:37 +08:00
@chf007 你也说了是服务器端调用,然后又说 appid 又是公开的,这不是自相矛盾么。另一方面,为什么一定要有 appid+appsecret 呢?只有一个 api key 不行吗?

OpenAI 的文档在这里,肯定是没有签名的: https://platform.openai.com/docs/api-reference/authentication
cheetah
2023-09-26 14:20:53 +08:00
@chf007 #42 另外也可以看看 GitHub 的文档 https://docs.github.com/en/rest/overview/authenticating-to-the-rest-api?apiVersion=2022-11-28 也是只有一个 key 放在 header 就可以的
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)
cheetah
2023-09-26 15:57:32 +08:00
@astkaasa 想表达什么呢?
erikk0
2023-09-26 16:38:53 +08:00
要加的。主要是为了防止一些不懂装懂的专家和相关人员没事找事制造内卷和 KPI 。
astkaasa
2023-09-26 16:47:27 +08:00
@cheetah 这是你转的文档里面写的
julyclyde
2023-09-26 16:47:36 +08:00
@GeruzoniAnsasu 如果请求者有 A 的签名,我就“认为是 A”
至于到底是不是,那无所谓
iyaozhen
2023-09-26 16:51:10 +08:00
需要,现在证书一般都是单向,还是可以中间人抓包,改请求的。加签能防止重放攻击类的
cheetah
2023-09-26 16:55:41 +08:00
@astkaasa #51 我知道,所以你粘贴这句话想表达什么呢?
gps949
2023-09-26 17:01:57 +08:00
抗抵赖。
事中确权,作为识别真实性的依据(如果你说的是 HTTPS 是双向的话,可以考虑不需要)
事后追责,作为日志完整性的记录。
xiqishow
2023-09-26 17:23:43 +08:00
如果使用单向 HTTPS 别说签名了,把请求/响应都用 AES 、SM 加密 仍然可以破解、仿造请求,比如你看看 bj301 的请求。
所以重要的是不要迷信单一的安全选项,尤其是 HTTPS
签名+时间戳还是能滤掉很多重放攻击,参数更改的,不能说完全没有意义
gadfly3173
2023-09-26 17:25:15 +08:00
@cheetah appid+appsecret 和单 token 是两种鉴权方式,对于不会有回调场景的应用来说,单 token 确实足够了,但是对于有回调场景(比如微信支付,题中这个大模型我没用过不知道),回调的时候就可以让业务系统根据 appid 来判断属于哪个商户/公众号,这样可以减轻业务系统的开发难度,可以直接在提供的回调接口的路径上写上 appid 来根据 pathVariable 判断。
回到你举例的文档和前面提到的 appid ,appid 的设计就是可以公开的,每个应用唯一的 id ,而单 token 模式下就没有这个可以区分的唯一标识了,使用哪种鉴权方式取决于产品的要求。
gadfly3173
2023-09-26 17:28:06 +08:00
@gadfly3173 接上文,微信中的 appid 和 mchid 的设计使得公众号可以嵌入指定的小程序,可以绑定不在同一个主体下的商户,也可以使得一个商户可以绑定对个公众号。在这上面的绑定过程中,appid/mchid 就是绑定的标识,而不是根据主体名称/公众号名称之类的信息
cheetah
2023-09-26 17:29:06 +08:00
@gadfly3173 #57 额如果是回调区分业务的话,完全可以在业务层面实现啊。这跟签名毫无关系。按我的理解,appid+appsecret 是 oauth 的产物
jianyang
2023-09-26 17:32:10 +08:00
私有接口很有必要、一定程度防止爬虫等
公开接口一个鉴权 token 就行了、其他多余校验、纯属麻烦自己麻烦别人

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

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

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

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

© 2021 V2EX