当前位置 博文首页 > 编程哲学家的专栏:API接口安全设计
? 前段时间写的《?API接口设计》中有粗略的谈了下API安全相关的东西,没有很深入的写API接口安全,所以这篇文章就重点谈一下【API接口安全】
token机制
对于简单的客户端身份验证一般都采用token机制,方便快捷,实现方式也很简单,复杂度也小,且安全性也很高,有很实用,这是众多API安全设计中“性价比”最高的方案。普遍用于表单提交、发送短信/邮箱验证码、反爬虫、商城下单、数据敏感隐私有安全性需要的接口...等。
这种方式的弱点是最怕的别人拿到token,一般是爬模板拿到。对于这个弱点,我的应对方法是配合多种验证来加强防防护,如验证请求头Request Headers里面的host、referer、cookie,你也可以自己定义请求头来验证,比如常见的:authority:,还可以把token放进js里,在发请求之前的时候动态添加上,还可以配合md5参数签名来加强安全性,可将token也一并带进参数签名。
客户端如何获取token的两种种方式:?服务器端返回token、与服务器端使用相同的加盐签名算法自己生成token。如果用第二种方式一定要做好代码混淆加密工作,不然就功亏一篑、前功尽弃。
?
appid、appkey机制
有些地方也叫client_id、client_secret,appid、appkey和client_id、client_secret是一个意思,一个概念。这种解决方案在对安全性要求非常高的时候才会采用的一种方法,因为极其复杂 ,例如支付.
给每个客户端分配一个appid和appkey,发请求的时候将appkey+参数+时间进行md5签名,得到signature,appkey的主要是用于参与签名算法,时间戳用于时效性验证,本次生成的这个signature可以使用多长时间,是1分钟还是半小时你自己定。请求的时候带着生成的signature+参数+时间戳+appid,服务端接收到请求后以同样的签名算法生成签名,并与当前发送过来的signature进行对比,如果不一致,说明参数被篡改过,直接返回错误标识。签名机制保证了数据不会被篡改,appid用于识别客户端的身份,appkey用于签名算法加盐,没有appkey签名永远无法通过。
关于签名规则,这个你可以根据情况自己调整,签名算法和服务器签名算法一致就行,常见的有以下几种:
还有一个token+appkey+参数+时间戳的,这种相当于又增加了一层验证,还可以再配合上前面提到的host、referer,让接口安全程度达到固若金汤的级别,我个人觉得再加token的意义不是很大。
安全需要更高的还有接口参数加密(注意不是参数签名,是参数加密,上面只是用参数来签名,但参数要是要明文传递),适合场景,公司内部两个项目组进行对接,为了防止接口被暴露和伪造访问,这个时候需要对参数进行加密处理,防止接口被其他外部人员调用,一般采用desc或者aes对称加密,约定好秘钥进行对接。一般采用desc或者aes对称加密,约定好秘钥进行对接.
?
?客户端安全
?在安全攻防中,保证客户端代码不被反编译、破解是尤为重要的,客户端代码里藏匿着与服务器端的交互方法、签名算法,客户端被反编译不但接口安全毁于一旦,可能还会暴露给攻击者服务器端防御最薄弱的环节。如果客户端安全没有做好即使你API接口安全做到再完善、再天衣无缝也无济于事,前面的努力全白费。假如骇客破解反编译客户端成功,就相当于釜底抽薪,前面的努力全白费,前功尽弃。
这就像木桶定律,一只水桶能装多少水取决于它最短的那块木板 ?。一只木桶想盛满水,必须每块木板都一样平齐且无破损,如果这只桶的木板中有一块不齐或者某块木板下面有破洞,这只桶就无法盛满水。
?
对于b/s web类应用,重要的js文件一定要混淆加密(比如配合token签名算法类js代码、文件),目前市面上有很多提供js加密的软件、网站,有收费的,有免费的。虽不能保证100%不被破解,但一个可靠的js混淆加密至少能保证90%的概率的不会被破解。对于一些安全要求极为苛刻的项目可以使用一些收费的js加密服务,有些混淆加密甚至可以达到95%~98%,你还可以进行多次反复加密。加密后可以找专业的安全公司来进行逆行工程测试,这样做基本就可以保证客户的安全了,当黑客在想拿你网站的数据,他需要衡量一下你的数据是否真的值得花费那么多时间和精力,甚至钱。
对于分布式c/s客户端的形式最重要就是保护安装包不会被破解反编译,否则接口安全设计再完美也没用。混淆、加密、加固一个都不能少,做完之后可以自己反编译个工具测试一下,之后对安全要求十分苛刻的可以再找安全公司做专门的安全工作。
不过由于token验证的方式比较简单直接,基本上不需要客户端做什么,反而对安全了许多,即使客户端被破解、反编译了都没什么。
?
一般安全有如下几方面:
为了不受网络、流量层面的监控,客户端与服务器端通信时要尽量使用https。
?实际项目中该采取哪种API安全设计方案?
web端一般采用token、md5算法 签名加密参数 ,对生成加密算法的js文件进行混淆加密,对安全性要求苛刻的,可进行多次反复加密,或者直接用付费的js安全加密服务
敏感性较高数据接口可以采用相对复杂的appid+appkey+md5算法参数签名,简单的用token,客户端加固加密混淆,对安全性要求极高找专业的安全公司来做客户端混淆加密。
另外扯个题外话,md5是一种签名,base64是一种编码,但总有人将这两种与加密的概念、名称弄混,成为他们为加密,你一定听说过有人说“md5加密”、“base64加密”。
总结:所有的安全措施都用上的话有时候难免太过复杂,在实际项目中需要根据自身情况、应用场景作出取舍,比如可以只使用签名机制就可以保证信息不会被篡改,或者定向提供服务的时候只用Token机制就可以了,如何取舍,全看项目实际情况和对接口安全性的要求。
这里只谈安全设计方案,不写具体实现,具体的大家可以参考各自的的语言自己实现,编程思想、解决问题的思路是可以跨语言的,不依赖具体实现,依赖抽象才是优秀的开发者应有的职业素养,代码只不过是实现的工具而已,这背后的思想才是解决问题的核心,就如同西方已经去世几百年的哲学家们,他们思想如今依然在影响着世界。
?
cs