客户端请求 API 时,一般要带上签名信息,签名参数用的密钥( secret key)怎么存储才能保证安全,还是说有其他更好的方案,比如放在服务端,大家一般是怎么做的。
1
dzdh 2023-08-22 11:31:04 +08:00
webauthn ?
|
2
EchoAI 2023-08-22 13:56:49 +08:00 via Android
我们目前是这么做的:Android 使用 so 文件,iOS 使用 a 文件,web 使用 wasm 文件。密钥和算法都在内部实现,同时做了很多防反编译的策略。
|
4
EchoAI 2023-08-22 15:40:08 +08:00
只要是密钥需要存储在客户端,就会被拿出来。只是时间的问题。绝对的安全是不存在的。
|
6
tool2d 2023-08-22 15:50:09 +08:00
我看到过的版本是密钥和时间强相关,客户端 6 小时就会变动一次,用算法生成的。
要破解密钥容易,要拿到算法还是有一点难度的。 |
7
0o0O0o0O0o 2023-08-22 16:08:10 +08:00 via iPhone
先说观点:放在客户端的全部都是能够被公开的东西。
> 安全部门说会被反编译出来 一些白盒密码方案大约就是为了应付这种情况,说是应付,因为它们和 #2 在一部分攻击者看来没有太多本质区别。 |
8
xiangyuecn 2023-08-22 16:08:22 +08:00
http 时代的遗留产物。
|
9
yinmin 2023-08-22 16:29:46 +08:00 via iPhone
一了百了的方案是改成不对称加密。客户端保存 rsa 公钥(是公开的,没必要保密),客户端用 rsa 公钥加密数据后上传,服务器用 rsa 用私钥解密。
直接从理论上解决问题。 |
10
edwardhodges 2023-08-22 16:38:50 +08:00
客户端不要直接请求这个 API 。客户端请求自己的业务服务器,然后服务器来请求这个 API ,密钥放在服务器就好了。
|
11
tool2d 2023-08-22 16:41:16 +08:00
|
12
mdn 2023-08-22 16:49:58 +08:00
@edwardhodges 业务服务器如何分辨是自己的客户端了
|
13
hsfzxjy 2023-08-22 16:51:33 +08:00
放在系统原生的钥匙串应该安全吧?比如安卓的 https://developer.android.com/reference/android/security/KeyChain
|
15
SteveRogers 2023-08-22 18:13:50 +08:00 via iPhone
密钥本地二次加密、二加密后的密钥分开存储,然后放到多处。
|
16
xiaoke 2023-08-22 18:16:36 +08:00 via Android
搭车请教,看到一些安卓 APP 直接把证书文件放在 assets 目录下,有风险吗?
|
17
0o0O0o0O0o 2023-08-22 18:22:26 +08:00 via iPhone
@tool2d #11 你说的这是客户端软件层面 **无解** 的事情(包括白盒),客户端的所有混淆都可以被分析所有逻辑都可以被模拟,只是难易度的区别。
> 分不清哪个是黑客签名,哪个是真客户端签名 这对应的应该是一个完整的风控系统,而不单纯是客户端该考虑的 |
18
iX8NEGGn 2023-08-22 21:54:43 +08:00 via iPhone
你没搞明白,国内大厂的 api 签名是为了防止重放攻击,参与签名的参数一般都包含时间,你这个属于 SSL Pinning ,为了提升绕过客户端请求的难度,破解是避免不了的,只是增加破解难度而已。
|
19
rocmax 2023-08-22 22:16:38 +08:00 via Android 1
一般应用加密只是为了防止篡改请求。如果你的应用真的需要用签名核实身份(例如比特币钱包类),请使用 HSM 。如果是手机应用的话内置加密模块有类似功能,可以保证密钥不离开硬件。
|
20
edwardhodges 2023-08-23 08:34:19 +08:00
@mdn 已经是业务服务器了,那就可以设置自己的登录等业务了。登录后获取 token ,用 token 来做校验不是常规操作?
|
21
mdn 2023-08-23 09:45:03 +08:00
@edwardhodges #20 客户端加签名在没有被破解的情况下都是 信任的客户端,token 无法证明是客户端请求的 API
|
22
edwardhodges 2023-08-23 10:09:41 +08:00
@mdn 是不是想复杂了。这个跟客户端没有什么关系吧,举个例子,token 根据手机号登录验证后获取,然后根据当前用户的 token 来请求业务服务器。业务服务器根据这个 token 判断是哪个用户,然后业务服务器再来调用比如 openai 的接口。就是说使用 secret key 调用三方 api 的行为是发生在自己服务器的。 而客户端的验证方式就是传统的验证方式,所有 app 都是这么进行的。 客户端就是被破解了又怎么样,最多知道了 api 接口(客户端里面没有保存三方的 secret key 这些信息),那又怎么样。
|
23
CodeCodeStudy 2023-08-23 10:15:18 +08:00
@yinmin #9 非对称加密太慢了,不应直接用非对称加密数据,而是用非对称加密对称加密的密钥,然后用对称加密数据
|
24
mdn 2023-08-23 11:07:48 +08:00
@edwardhodges #22 客户端加签名,想要防止某些用户绕过客户端直接请求接口,比如签到等功能,token 用户自己也能看到,签名需要用户破解
|
25
IvanLi127 2023-08-23 13:43:42 +08:00 via Android
签名是防谁篡改负载?防非法用户篡改用登录凭据,防网络链路爱咋存咋存,防合法用户那得靠硬件了。
|
27
EchoAI 2023-08-23 14:24:34 +08:00 via Android
@edwardhodges #22 客户端被破解了,不仅知道了 API ,用户的 token 也能被拿到,还省得去破解密钥了,直接使用 token 请求 API 就可以了。
|
28
tool2d 2023-08-23 14:31:58 +08:00
@msg7086 你普通 ssh 连接,服务器可以设置客户端指纹的白名单。就算黑客有密码和密钥,只要客户端指纹不对,服务器也是可以拒绝请求的。
客户端被挟持发请求,和黑客第三方 IP 发起恶意请求,对服务器来说,还是有区别的。 |
29
edwardhodges 2023-08-23 14:46:44 +08:00
又看了下讨论,如果想把请求绝对限制在自己指定的客户端里,理论上只能增加难度,无法绝对的。不清楚大家的需求,感觉这个需求本身意义就不大吧。 使用加固混淆等方式,增加客户端 app 被破解的难度,所有请求必须使用信任机构颁发的证书的 https ,不在客户端存放重要的信息,验证流程通过服务器来校验。这些操作下来,理论上已经很安全了吧。
|