当前位置: 首页 > 科技观察

一种基于签名算法且简单安全的API授权机制

时间:2023-03-20 18:05:29 科技观察

基于签名算法的简单安全的API授权机制可以说这是裸奔的接口,但是这个接口对安全性要求不高,只能防止恶意调用和验证通道身份。去年笔者写了一个API统一授权平台,对内部服务开放接口对第三方系统调用进行统一授权管理。除了方便管理接口授权外没有别的目的,但是部署成本高。这一定是我做过的最没有意义的项目之一。今天介绍的API授权机制,也可能是一种被广泛使用的API接口授权机制。记得笔者以前做微信支付功能的时候,微信提供的支付接口也是用的这种方式:签名。优点:简单,对性能无影响,无额外成本。这种授权方式的实现逻辑是授权人为每个接入平台设置一个唯一的身份(密钥)和一个独立的密钥,实际上相当于一个账号密码。接入系统每次发起请求时都需要在请求头中携带三个参数,分别是身份(密钥)、请求的时间戳和签名。授权系统在收到请求时验证签名,验证该请求才被批准。验证签名的过程是从请求头中获取密钥和时间戳,然后根据密钥通过相同的算法生成签名(调用方和授权方使用相同的签名算法),最后比较签名是否正确得到的请求头是否相等,如果相等,则验证成功,否则验证失败。基于签名算法的授权方法的实现过程如下:授权方:1.定义签名算法,向接入方提供签名生成算法,为接入方生成密钥和身份;2.拦截需要验证签名的项目接口,从请求头中获取时间戳和身份,根据密钥和签名算法生成签名,将生成的签名与从请求头中获取的签名进行比较,如果是同,继续第3步,否则拒绝请求;3.请求时限有效性验证,将当前系统时间戳与从请求头中获取的时间戳进行比较,如果请求在有效时间范围内,则释放请求,否则拒绝,响应签名过期。接入方:1.从授权方获取连接文件,向授权方索取密钥和身份;2.根据文档提供的签名生成算法封装签名方法;3.发起请求时,将身份、当前时间戳和签名写入请求头。签名生成算法可以自定义,比如将身份(key)、时间戳(timestamp)和key拼接在一起,然后使用不可逆算法对字符串进行加密生成签名,比如MD5算法。规则越复杂,它们被打破的可能性就越小。在签名中添加时间戳有什么好处?一是增加签名的时效性。授权系统可以将请求时间戳与当前系统时间戳进行比较,限制签名在一秒内有效,或者在五秒内有效。但是双方的系统时间必须是正确的。第二是安全。如果黑客拦截了你系统的请求,然后修改请求,再发起请求,这期间肯定是需要时间的,所以当系统收到被篡改的请求时,签名的有效期已经过去了。如果请求头中传递的时间戳发生变化,授权系统生成的签名将与请求头中传递的签名不同,请求也将失效。即使知道被授权方(肉鸡)系统的签名规则,如果不知道密钥,也无法生成有效签名。并且由于签名采用了非对称加密算法,所以几乎不可能通过爆发力破解密钥。那为什么要使用时间戳而不是格式化时间字符串呢?这可能是由于时区的兼容性。如果不同机房的时区不同,时间会不一样,但是时间戳是一样的。为了充分发挥这种授权方式的安全性,首先生成签名的规则必须足够复杂,其次签名的加密算法必须是不可逆的,绝不能使用Base64算法,最后密钥必须足够长并且足够复杂以确保即使知道签名生成规则,也不可能通过暴力破解密钥。签名规则是指加密前生成签名串的规则,如:key+key+时间戳+key+key。假设密钥为“app”,密钥为“123”,时间戳为“1111111111111”,拼接生成的预加密签名为“app1231111111111111app123”,最后通过对拼接的加密即可生成最终签名字符串通过加密算法。每个接口都写签名逻辑不是很麻烦吗?不需要。对于授权方,可以通过过滤器或者拦截器来完成签名验证逻辑;对于调用者来说,不同的框架有不同的方法,但是我们总能想办法把签名逻辑只写一次吧?本文转载自微信公众号“Java艺术”,可通过以下二维码关注。转载本文请联系爪哇艺术公众号。