第三方的 key 和 secret 存放在移动客户端是否安全?

2018-03-04 23:36:23 +08:00
 mdate

最近委托其他公司开发 APP,他们告知把第三方的 key 和 secret (将近 10 个第三方接口。融云、个推、微信、微博、友盟等等)存放在移动端,我觉得不怎么安全,另外考虑到实际运营过程中,如果账号出现问题写在后台只需要重新申请账号获取密钥填写即可,写在端就得更新端,成本比较大。考虑到这些联系后对方的回复是: 1、业界大都这么做,包括很多有名的大型 APP 2、存放在移动端比做到后台填写调用更安全,写到后台数据库容易被抓包 3、存放在数据库然后调用,操作起来很麻烦

在网上也搜了下相关资料,据说存放在端的密钥特别是安卓 APP,很容易被编译破解。 萌新请问各位 APP 开发大佬,第三方密钥写在端好还是后台好,你们平时都是怎么处理这类问题的呢?他们这么做是否安全?如果不安全,具体要怎么处理呢?

5472 次点击
所在节点    程序员
17 条回复
linyinma
2018-03-05 09:29:23 +08:00
( 1 )首先没有绝对的安全概念,在能承担的风险内都是安全的;
( 2 )其次任何一款产品都是和需求息息相关的,以人为本,不要过分强调安全而忽略了使用;
------------------------------------------------------------------------------------------------------
楼主在提问题一看也是经验比较丰富,提到终端安全性,运营过程密钥更新问题,其实你都有答案了:
1,直接存到终端肯定是不可取,我们先不关安全,就那密钥更新这个点(涉及 10 多个第三方),不可能更新密钥要求强行更新 APP 了;
2,存到云后台,每次使用都有后台进行密钥运算,也是比较笨重的;

但通常的方案也是折中方案: 比如使用的会话密钥(密钥包含下属性: 和机器序列号有关,有有效期,有使用次数..)降低直接固化 APP 带来的风险,也减少全部在后端进行运算带来的(非脱机性,后台负担等)
yzxhzxsw
2018-03-05 09:35:25 +08:00
绝逼不安全,且不符合规范,这些应该都是通过接口,后端生成第三方请求数据给客户端调用
mdate
2018-03-05 10:30:24 +08:00
locoz
2018-03-05 10:32:27 +08:00
确实挺多大型 APP 都这么做
mdate
2018-03-05 10:33:52 +08:00
@linyinma @yzxhzxsw 具体应该怎么操作呢?是存在终端,然后做好加密?还是存到后台?还是区别对待,部分存到云后台部分存在端?你们平时开发 APP 都是怎么处理的啊?
enenaaa
2018-03-05 10:45:46 +08:00
如果是非对称密钥, 放在客户端也没什么安全问题
linyinma
2018-03-05 11:15:20 +08:00
@mdate 存终端我先不分析是否安全的问题,而是密钥更新带来的强行更新 APP 带来不友好的体验,APP 的好感已经打折了;我想这个第三方密钥不是在使用过程中需要直接传送,而是用来运算的, 那么为什么不在后台去运算,然后返回 APP,让 APP 直接使用; 当然 APP 与后台交互需要密钥包含,一个非对称密钥就搞定, 服务器将公钥写的 APP 中,不用保护直接使用, 交互的时候 APP 生产会话密钥,用公钥保护, 就是 HTTPS 握手那一套机制~~
bianjp
2018-03-05 11:55:50 +08:00
只做过后端开发,没做过客户端开发。我觉得,只能保存在服务器端。
按第三方接口的认证方式可以分成两类:
1.直接传递 key:这种情况下只能用服务器端中转客户端到第三方的请求;
2.传递由 key 计算得到的某种短期 /临时 token:客户端请求服务器返回一个可用的 token,再用此 token 直接请求第三方。
1 的优势是服务器端掌控一切,想干嘛干嘛(比如权限控制、统计),而且方便更新,劣势是增加服务器负载;
2 的优势是服务器负载小,请求响应快。很适合上传文件这种流量大的请求。
janus77
2018-03-05 13:06:18 +08:00
你说的是 key 还是密钥
key 的话一般是固定的,服务端校验方也是第三方的服务器而不是我们,这种东西一般不属于核心模块,是可以直接放本地的
密钥的话,服务端校验在自己的服务器,也有可能是可变的,这种是可以通过接口请求的,但是如果太大或者一般是写死的话也是可以放在本地的(如 https 自签名证书)
————
安全问题,本地存放一般使用多种加密手段结合,相对最安全的话就放在 so 里面了,但是有些东西由于第三方配置要求是无法这样做的,因为第三方接口是要求在 APP 启动的时候进行自校验初始化的,不能在启动之后获取。
其实直接写到 gradle 或者 manifest、string.xml 甚至 java 硬编码 问题也不大,业界确实是很普遍的做法。
leekafai
2018-03-05 13:25:06 +08:00
只要传输不带 secret 基本没问题,如果代码被反了,那就不是 secret 在哪里的问题了……
一般都是带签名提交,key secret 放在客户端没关系。
mdate
2018-03-05 14:02:03 +08:00
@janus77 @leekafai 如果 APP 在实际运营过程中,账号出现问题了(因为第三方接口账号太多,所以可能出现问题的几率也比较大,并且实际运营中的情况也可能比较复杂),这时候换账号重新生成 KEY 等就必须更新端,然后上架,然后引导用户去下载更新,成本是不是更大呢?
mdate
2018-03-05 14:06:30 +08:00
@bianjp 按你以往开发后端的经验,一般的 key 和 secret 都是在后台设置更改的多还是?拿 WX 登录、WX 支付、weibo 登录、消息推送、即时聊天、天气、ALIPAY 支付等等为例,使用这些第三方接口在安全便捷和服务器负载两方面选择哪个比较好呢?
janus77
2018-03-05 16:35:38 +08:00
@mdate #11 不知道你说的重新生成 key 是什么意思
我理解的 key 是对你客户端的一个标识,是一个项目一个 key 而不是一个用户一个 key。
类似分享 IM 支付 之类的这种,一般是不会出问题的。
出问题不一定要换 key ;
换 key 不一定频繁,因为很多厂家的 key 其实就是根据包名+算法算出来的,只要包名不换就不需要换 y ;
如果换 key 肯定是 sdk 厂商负责,而且是大面积的而不仅仅是你一家。
换 key 先例我的记忆里找不到。凤毛麟角。
而且就算要换,发个新版本是很正常的事,APP 更新难道很被抵制吗?

至于你说的换 key&&频繁,是不可能同时出现的,至少没有先例。
Raidal
2018-06-06 23:17:47 +08:00
0. 服务端开放下发第三方 appkey 和 appsecret 的接口,步骤如下
1. 服务端生成公私钥对,并把公钥提前预置在客户端上
2. 客户端生成随机 key (临时存放到本地),并用公钥加密发送给服务端
3. 服务端私钥解密出随机 key,并将随机 key 作为密钥使用对称加密算法加密待下发给客户端的第三方 appkey 和 appsecret
4. 客户端通过接口获得加密后的值,并用之前生成的随机 key 作为密钥解密出第三方 appkey 和 appsecret,并临时存放到本地
5. 客户端使用第三方 appkey 和 appsecret 的过程中一旦发现出现问题(提前在客户端代码中),开发人员可以上第三方平台申请更换密码。客户端重复上面的步骤拿到新的第三方 appkey 和 appsecret。
hack2012
2020-05-03 10:33:59 +08:00
@Raidal 这个方案还不错的,其实可以客户端也生成公私钥对,然后将公钥内置到服务端,服务端使用公钥加密第三方 appkey 和 appsecret,然后发给客户端,客户端使用私钥解密。。不过这样做需要 app 端做加固处理,防止反编译。
ongongethan
2023-08-22 22:47:22 +08:00
@Raidal 如果其他人反编译拿到了第 1 步里“客户端上提前预置公钥”,后面的 2 ,3 ,4 ,5 步骤都可以通吧
ongongethan
2023-08-22 22:48:05 +08:00
@Raidal 通 -> 走通

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

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

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

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

© 2021 V2EX