互联网和产品 · 2019年12月11号 0

如何设计B端SDK和API的激活与安全机制?

1. SDK和API的区别

首先我们简单来讲一下SDK和API的区别。

1.1 什么是API?

API,全称Application Programming Interface,即应用程序编程接口。

API其实就是把做好的功能,封装成各种预先定义好的函数,其他人想使用这些已有的功能,只需要调用这些函数,并传递必要的参数即可。

API的主要作用是,程序员不需要深究API背后功能实现的具体逻辑,程序员只需要直接调用API就可以使用其背后的功能逻辑,这节省了程序员一大部分的工作,大大提升了效率。

如何设计B端SDK和API的激活与安全机制?

举个例子:

银行的窗口就类似一个个的API,他们分别有不同的功能,比如取款、存款、对公等业务。

而我们预先填好的表格信息,交给窗口的工作人员,就是传递必要的“参数”信息给这个窗口API,然后使用它的存款功能。

我们不需要理解工作人员具体需要哪些操作,其中涉及多少复杂逻辑。

只需要来到窗口(调用API),上交表格(传递必要信息)就能使用该功能服务。

1.2 什么是SDK?

SDK 就是 Software Development Kit 的缩写,翻译过来——软件开发工具包。

这是一个覆盖面相当广泛的名词,可以这么说:辅助开发某一类软件的相关文档、范例和工具的集合都可以叫做SDK。

SDK可以简单的认为是一系列API的程序包集合。在这个程序包中是一个完整的软件功能,这份程序包几乎是全封闭的,只有一个小小接口(API)可以联通外界。

如何设计B端SDK和API的激活与安全机制?

还是刚刚银行的例子:

可以把银行看做是一整个SDK,银行SDK程序包能帮你完成存款、取款等业务。

银行SDK唯一联通外界的就是它的大门,或者说是取号机(API),只有进入银行然后取号,才能在不同的窗口办理服务。

而这些不同的窗口,就可以看成一个个不同功能的API接口。

2. API的接入安全机制

安全机制,其实是为了保护我方后台,主要有两点:

  1. 不被不明身份者访问
  2. 不被恶意大量的请求攻击

先来简单说一下API的接入安全机制。

API的安全机制设计主要考虑两个方面:

  1. API接入方案如何避免接口盗用(防止不明身份者访问)
  2. Http接口请求如何避免攻击(防止被恶意大量请求攻击)

第一个方面,需要客户对自家的后台做一层封装,然后我们后台仅接受客户后台接口传递的请求。

第二个方面,需要在我方后台建立IP白名单,提供给客户后台,方便双方进行加密验证。识别哪些是客户的请求,哪些是恶意请求。

如何设计B端SDK和API的激活与安全机制?

3. SDK的接入安全机制

为了防止客户拿到我们的SDK以后白嫖,或者为所欲为,我们需要在客户接入SDK,请求我方服务的时候进行激活校验。

就像是我们买票进站乘车一样,需要出示身份证和车票进行校验方可通过。

SDK最终都是会被集成到硬件设备中提供服务,尤其是AI公司的技术方案,不管是视觉还是语音,最后交付的都是硬件产品。

通常激活的时机,都是在硬件设备进行第一次启动的时候进行。

SDK的激活涉及到我方对客户的计费,所以激活逻辑的设计要非常的仔细和严谨(毕竟都是钱哪。。)

一般来说,SDK的激活方案可以分为三种(以下说法参考思必驰的产品授权方案):

  1. 预烧录
  2. 预登记
  3. 动态注册

预烧录,指的是,我们后台预先生成授权的license文件,然后预先写入硬件设备的存储文件中。在设备首次启动的时候,就直接调取license文件进行激活。这种方式适用于需要不联网提供服务的场景。

预登记,指的是,预先登记设备白名单,以用户设备注册激活的一种授权方式。这种方式适用于客户提前知道所需授权设备的设备标识的场景

动态注册,指的是,每次设备激活,后台动态给这些设备进行激活并注册的一种形式。这种方式适用于客户可以提供设备的唯一标识,但是提前不知道哪些设备需要授权,不知道有多少设备需要授权的场景。

下面想主要讲一下,我在设计预登记和动态注册时遇到的一些坑。

3.1 预登记对我方友好,但是对客户不太灵活

预登记方式其实对我方来说是比较友好的,因为客户提前提供准确的设备唯一标识的时候,我们可以很方面的进行激活和统计,说直白点,就是方便收钱。

所以,客户为了省钱,有可能采取作弊策略:将一个设备的唯一标识给多台设备进行使用

因为设备标识,一般是设备序列号(SN),对于硬件厂商来说是可以自己按照一定的规则随便刷的。

那为了防止被客户白嫖,我们自然要设计一套防作弊策略:不仅仅采集客户提供的设备序列号,还要采集一些设备的其他信息进行辅助判断,该序列号只绑定了一台设备

如何设计B端SDK和API的激活与安全机制?

当客户想白嫖我们,将设备A的序列号给设备B使用,那么在激活校验的时候,就会发现设备B的序列号关联的信息和我们记录的信息(设备A)不同,如此就可以认定客户是想白嫖,激活失败。

上述方式看起来比较完美的解决了客户作弊的问题。但是对于部分客户来说就会造成不便。

有些客户在对接SDK后,会进行测试。在测试的过程中,客户会不断的对硬件设备进行刷机、恢复出厂设置等骚操作。

而刷机、恢复出厂设置会改变设备的信息(例如AndroidID),那么就会造成同样的序列号在同一台设备上不能激活了。

因为刷机改变了它的设备信息,我们会认为这不是同一台设备。

你可能会说,那客户再写一个序列号不就行了,反正客户可以自己刷序列号。

客户是上帝,你不能指望客户去干这样的累活。当然是我们来优化了。

为了解决这个问题,我们想到一个方案:超级序列号。这个序列号必须是我们来生成(可控),拥有无限次激活,可以在多台设备上使用的超能力

但是为了防止客户拿这个超级序列号白嫖我们,我们需要给这个超级序列号设置时间限制。在有效时间内可以随意使用,一旦过了有效期就会失效。

如何设计B端SDK和API的激活与安全机制?

3.2 动态注册虽然灵活,但是对于统计来说麻烦

动态注册就是在设备第一次启动激活的时候,上传设备的信息,包括:序列号、MAC(蓝牙+WiFi)、IMEI和AndroidID

但是这些信息不一定能获取到。

IMEI,国际移动设备识别码(International Mobile Equipment Identity,IMEI)

IMEI本该最理想的设备ID,具备唯一性,恢复出厂设置不会变化(真正的设备相关)。

但是Android6.0以后,就需要用户授权才能使用,而且在Android10.0以后,就会彻底拒绝获取IMEI。

并且,IMEI其实只有通讯的设备才会有,如果没有通讯(简单理解,就是电话卡)模块的话,也不一定有IMEI号。

序列号(SN)

设备序列号由厂商提供,如果厂商比较规范的话,序列号应该是唯一的,也不会随刷机或恢复出厂设置等改变。

但是你不能把利益建立在人性的基础上,那太不靠谱。所以序列号,其实更多只能作为辅助信息来进行判断。

MAC地址

MAC地址一般指蓝牙MAC、WiFi Mac或者是两者的拼接。但是获取同样需要权限,而且如果设备没有蓝牙模块,没有WiFi模块的话,也不一定有MAC地址。

Android ID

Android ID 是获取门槛最低的,不需要任何权限,64bit 的取值范围,唯一性算是很好的了。但是不足之处也很明显:刷机、root、恢复出厂设置等会使得 Android ID 改变

所以,我们在设计动态注册激活逻辑的时候,就需要考虑到这些情况。

动态注册的激活逻辑,就是每次激活的时候,后台记录设备上传的四个设备信息(有的不一定有)。

然后每次其他设备激活的时候,就把该要激活的设备信息在已激活的设备信息记录中进行比对,比对的规则有两方面:

  1. 所上报的设备信息种类是否一致,种类指的是四种设备信息
  2. 所上报的设备信息是否一致

如何设计B端SDK和API的激活与安全机制?

这样的激活逻辑,虽然能保证最大程度的识别出不同的设备,但是会给统计激活设备上(统计是为了收钱)造成麻烦。

例如,AndroidID,会随着刷机、恢复出厂设置而改变。这就会成为客户扯皮的点。

客户会说:“我并没有更换设备,只是因为设备故障需要刷机或者恢复出厂设置,你就多收我一台设备的钱,当我是冤大头吗?”

虽然这可以通过商务的手段去解决,但是还是那句话,客户是霸霸嘛。

其实,从上面我们描述四大设备信息的特征来看,AndroidID具有如下优秀属性:

  1. 一定能获取到;
  2. 只有刷机操作才会改变,无法人为指定。

所以,完全可以以AndroidID作为主要依据,只要AndroidID一致,不管其他参数种类和参数值是否相同,都可以认为是一台设备。

我们只需要找出那些,因为刷机或恢复出厂设置导致AndroidID改变的设备,而这些是客户扯皮的主要部分。

因此,在我们给设备动态注册的时候,要采用严格的规则,只要有一点不一样,就重新注册设备信息。

但是在统计激活的设备信息上,可以根据一定的规则,将具有争议的注册设备信息给统计出来,做到扯皮也是要有准备和技术含量的。

如何设计B端SDK和API的激活与安全机制?

SDK 和 API 是公司输出技术的主要手段,而如何设计激活逻辑和安全机制,是保证公司不被白嫖的手段,需要认真和谨慎的考虑。