安全密钥管理

API接口签名验证/开放平台鉴权

app_key:同账号
app_secret:同密码, 表示你真的拥有这个权限
用来申请一个token,access token过期失效

调用第三方的key/secret,保存在客户端APP还是服务器端?

推荐保存在服务器端,客户端储存密钥一定是不安全的

1
2
3
4
5
6
7
8
#### 调第三方接口,是客户端调还是服务端调?
理想情况:
1、客户端用App_id去调WX、weibo、AliPay,拿到code
2、服务端用code也去调第三方接口,获取access_token,返回给客户端
#### 存在服务端,调用麻烦,传输secret?
是的,发送key/secret给客户端,同HTTPS握手阶段一样,产生一个随机会话密钥,加密发给APP,APP解密后再去调第三方接口

TIPs:第三方secret不是在使用过程中直接传送,而是用来运算的(签名校验)。建议服务端去运算返回APP,让APP直接使用

按第三方接口的认证方式可以分成两类:
1.直接传递 key:这种情况下只能用服务器端中转客户端到第三方的请求;
2.传递由 key 计算得到的某种短期 /临时 token:客户端请求服务器返回一个可用的 token,再用此 token 直接请求第三方。
1 的优势是服务器端掌控一切,想干嘛干嘛(比如权限控制、统计),而且方便更新,劣势是增加服务器负载;
2 的优势是服务器负载小,请求响应快。很适合上传文件这种流量大的请求。或者直接传递key

结论

1、存放在APP端不可取,密钥更新必须强制更新APP
2、折中方案:使用会话密钥,避免直接固化secret在APP,也减少全部在后端运算负担。

白盒密钥

对称密钥的key在内存运行时依然是明文的,白盒密钥实现在内存中是密文的

AES加解密

明文10M文件,AES加密后也是10M密文,密钥是固定256位,密文存储用的是BASE64(你看到的密文是BASE64处理过的,即使解密也是乱码)

Q&A


Q:前端加密敏感数据,密钥存放在哪里?不让硬编码在JS中,那放哪?
A:前端加密password等敏感字段,是用后端的公钥加密的,公钥可以硬编码在js中。
A:前端随机产生一个key,用来AES加密数据,然后用后端公钥加密key,一起传给后端。


Q:密钥硬编码在代码中,有安全风险,那密钥存在哪里?后端的代码可以硬编码么?
A:后端硬编码不在公网上传输,其实也是安全的,但不推荐,不合规。


Q:已经使用了HTTPS,前端加密是否有意义?
A:HTTPS并不是端到端(End to End),而往往中间夹杂着代理,有客户端代理也有服务端代理,他们自然就可以看到用户https明文流量,其中也包含用户的明文密码。一旦前端加密了用户密码,即使有代理的存在,依然无法获取明文密码。


Q:前端应用中的API密钥如何保存?
A:应该使用后端获取API的结果,返回给前端。