架构师04-应用服务间加密设计和实践

Posted 飞鸟在途

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了架构师04-应用服务间加密设计和实践相关的知识,希望对你有一定的参考价值。

最近在学习应用服务间加密的设计和实践,结合十几年碰到的各种情况聊聊都是怎么实现的,需要注意哪些点。

 为什么需要加密 

主要还是安全问题,即使内网也是不安全的,团队间相互信任是一个方面,不同服务间需不需要做一定的业务内容加密又是另外一个方面。例如:A业务调用B接口url传入了业务需要的参数,而这个内容恰巧被C获得,那么如果没有进行必要的参数内容验证处理,那么C就可以通过修改参数获得其他内容,特别是对于一些以主人态uid获得的内容。而一套加密机制可以保障C除了获得A请求B的参数对应的内容。无法获得此接口之外的信息,即:无法通过修改参数获得多余的内容。我曾经遇到过几次,安全部门提过来的漏洞,都是由于没有加密而造成的。加密是在一定业务场景下的加密,目的是防止业务参数被篡改,获得其他非法的内容,所以任何方案都是在一定业务场景下根据内容的考虑。

 服务器间加密需要反解吗 

答案是通常不需要,我所碰到的业务场景都是只验不解。这主要是因为成本问题,既加密又解密的算法,比只加密的算法难度高,虽然有很多加密算法实现了这个功能,但如无必要还是不要考虑,服务方按照一定的规则生成加密token和业务方传过来的比较就好了。如果需要拿到指定的参数,比如loginUid,那么把uid做为加密串的一部分就好了。

 业务调用的流程 

简单说,就是业务方和服务方约定一个加密因子(appsecret),然后经过加密算法对包含加密串,生成一个加密的token,然后调用服务方接口的时候,传入。而如果一个服务方对多个业务方的时候,为了标识是哪个业务方,为每个业务方分配个appkey,调用接口的时候带上就可以了。token的生成算法如下图所示:

token=AOE(appsecret + 内容)
// 内容主要指请求参数等

 token具有什么特点 

  1. 时效性

token加密串往往设计成有实效的,即同一个token在一定时期内有效。实现方式是在加密算法AOE么,肯定不是,那么基本是在加密因子上,而加密因子包含两个部分appsecret和内容,有些场景是通过不断的更新appsecret进行达到时效性的,不过这种方式成本比较高需要额外的服务支持。当然还有一种方式,比如内容里增加个时间戳,每次先判断时间戳是不是符合要求,然后在进行加密,这种方式也是之前我接触的一些开放平台使用的一种方式,我个人认为这种方法在保证基本功能基础上,更低成本。


  1. 唯一性

通俗点儿说,就是每次请求的token都不同。当然也可以根据业务场景只限定一些关键字段,如登陆uid等。我所碰到的基本是两种方式:

(1)全内容参与加密,即:所有的请求参数按照一定顺序排列(例如升序),然后组合成规则的字符串在通过AOE算法进行加密。前几年的SNS社交开放平台基本上是这么实现的,这样修改调用接口带的任何参数都会导致验证失败。

 (2) 部分重要内容参与加密,即:如上所说登陆目标用户loginUid参与加密,确保token是基于loginUid生成的,即使被截获也不能以其他uid的身份去请求一些内容。

 token放在哪里 

  1. 放在uri参数里面,之前碰到的一些常见是放在url参数里就好。这样的优势是简单,方便统计,如果服务器使用了nginx access日志进行统计监控数据收集,可以很方便的手机到appkey等内容。

架构师04-应用服务间加密设计和实践_时间戳

  1. 放在header里面,博内部平台的验证是放在header里面的,我猜测当时这样设计是想同业务参数分开吧。

 几种加密方式 

下面介绍我在开发过程中用到的几种方式:

1.无加密

有些同学认为内网很安全,所以开发接口不进行必要的加密。这种方法安全等级=0。

2.约定固定字符串

这种方法跟第一种差不多,只不过双方约定个字符串。理想状态:其他业务方不知道其他业务方的字符串,所以无法调用,这种方式防备不了请求被截获的问题。

3.约定固定字符串对字符串进行加密

两方约定好appsecret、appkey,然后为了不侵入业务,直接根据appsecret进行加密得出token,这种方法稍微比上面好些,说明开发人员有一定的安全意识,但是依然解决不了安全问题,固定的一串内容经过加密算法得出的还是固定的另外一个加密串。解决不了url通过修改参数可获得数据的安全隐患,安全部分那里依然不过关。

4.约定固定字符串然后结合内容加密

很多时候只是业务方,调用服务方的一个接口,没有必要整的那么复杂,这时,服务方和业务方线下约定好token_secret和一个加密方式AOE即可。

架构师04-应用服务间加密设计和实践_加密算法_02

当然这种方式一般加入时间戳,登陆uid等进行加密生成token。

5.周期变换加密因子token_secret,然后结合内容加密

这种方式是某博内部平台广泛应用,调用方以最长天级为单位(保证实效性),定时刷新对应业务appkey的tauth_token和tauth_token_secret,业务调用服务方时在根据一定的算法实现token 放在header头里面。

token=AOE(tauth_token_secret + 内容)

架构师04-应用服务间加密设计和实践_加密算法_03

更新:这种方式是通过额外的定时任务周期性的刷新tauth_token_secret的内容。

成本:这种方式成本比较高,需要服务方提供token生成服务,而业务方需要另外的进程去刷新secret的内容。而为了保持高可用,token 生成的机器必须两台以上机器。

产品化

自古深情留不住,总是套路得人心。如果是一两个接口,一两个业务方,那么约定下固定的加密因子就好,没必要做成一套体系,这也是我在开发过程中观察到的。但如果服务方对应多个业务方调用,还是要遵循一定的规则,提供必要的wiki支持,另外配置信息也要做成后台管理系统:

架构师04-应用服务间加密设计和实践_字符串_04

如下内容,服务提供者开发新接口,然后配置调用业务方的权限和appkey, appsecret,限定接口等内容。然后告诉业务方,业务方按照wiki说明调用业务需要的接口,使用appsecret进行加密调用。如上面的图,标准化,体系化。

总之,大家一定要结合应用场景做技术方案,如果没有几个业务方,就没必要搞token中心。如果没有token的自动变换,就依赖时间戳来变更。两种方式都没问题,看哪种方案成本能接受即可~

以上是关于架构师04-应用服务间加密设计和实践的主要内容,如果未能解决你的问题,请参考以下文章

唯品会滴滴沪江架构师,关于微服务粒度高可用持续交互的实践分享交流(上)

唯品会滴滴沪江架构师,关于微服务粒度高可用持续交互的实践分享交流(上)

IaaS首席架构师的架构设计思考与实践

百万年薪架构师必备能力:万亿级微服务架构设计实践!

鲸品堂|复杂业务系统高扩展架构设计与实践

个推首席架构师俞锋锋:基于OpenResty和Node.js的微服务架构实践