工作笔记 - GOTP实现的系统间集成的认证

107 阅读7分钟

概述

应用系统之间进行业务集成,通常涉及到相互间进行认证的过程。这里面可以有很多的技术方案,比如公钥签名验证、访问控制令牌、APPID/SEC等等。但笔者觉得这些方案多少都有一些过程繁琐,不易使用,安全性不足等等问题。

在此,笔者提出了一种基于OTP(一次性密码)技术的应用系统间集成认证的技术方案,可以在一定程度上改善上述的问题。和以前的技术方案比较,笔者提出的技术方案有以下特点:

  • 实现和操作简单

基本上做到了单一文件实现,无须依赖复杂庞大的第三方程序库。整个实现核心代码不超过100行。另外,代码的移植和使用也非常简单,密码的生成、修改和录入也很方便,读者应当可以从示例程序中有所体会。

  • 不需要缓存或者持久化系统

传统的方案,通常需要应用系统应用某种持久化系统,来缓存Token并进行校验,文中提供的技术方案不需要这一点,它使用计算的方式,来检查token的有效性。

  • 安全性较好

所使用的验证信息是动态的,可以很好的避免Token泄漏的问题。因为可以做到每次验证Token都是变更的。而且,密钥的原文只在应用系统内部使用,其任何固定衍生和相关信息都不会在网络和应用过程中传输(想想微信那个APPID和SEC?)。

  • 扩展性强

用户可以根据自己的需求,对安全性和认证过程进行扩展。如使用更长认证码,更短的变更周期等等。

  • 场景适配性好

可以同时使用同样的方式,实现应用系统之间的操作认证,和系统与用户之间的操作认证。如可以将数据操作接口,方便的改成需要用户参与的系统管理操作接口(如通过管理客户端工具+验证码进行操作),并保证操作的安全。

GTOP实现和改进

关于GOTP本身的原理和实现,不是本文主要探讨的问题,笔者也在其他的文章中进行了阐述。这里选择的GOTP是指核心使用和Google Authticator兼容的OTP生成算法。这一可以方便的实现兼容的多因素认证。

本文所涉及的技术方案的主要的内容,就是在此基础之上,对GOTP的实现进行改进和封装,使其更适合的应用到实际的业务系统当中。下面是基于Bun的GTOP和改进的参考实现,独立运行,无三方依赖:

示例代码中的主要改进包括:

  • 实现了多个单例模式,可以在同一个应用中,支持多个预配置OTP实例,这个特别在中央服务器端,需要支撑多个边缘应用的场景中特别有用,它们可以使用不同的安全配置

  • 实现了方便的Code、Token和验证的方式,方便使用和集成

  • 在GTOP基础上,实现了简单的对称(共享密钥)信息签名和验证

  • 信息验证操作有一定的裕度,可以处理由于两端时间不精确同步或者时间片边缘交错的情况(示例是150秒窗口),降低由于这些因素造成的操作失败的概率

这个算法的原理并不复杂,但其中有很多技术细节会导致可能出现和预先不同的结果。其中最容易出错的就是所使用的密码是有格式限制的,笔者在之前不了解的时候出了很多问题。它其实是一个Base32字符串,也就是字符的范围是AZ,27,所以算法在实际使用的时候,会将其按照Base32规则解码成为字节数组来使用的,并不是简单的字符解码。另外密码长度也有要求,起码不能太短,笔者的随机密码生成的建议长度是16个字符。

要验证这个算法实现的正确性,也非常简单,就是安装一个Google验证器,然后使用一个密码创建一个验证项目,然后使用同样的密码运行程序,检查生成的验证码是否相同。而且,虽然在使用验证器软件的时候,很多情况为了方便,是扫描录入的,本质上也是将这个密码编码成为QR图片,和手动输入没有什么区别,都是一个Base32字符串。

从算法实现中,我们也可以看到,GOTP的安全性,主要体现这个“可变性”上,在某一时刻只有一个正确的密码,虽然密码本身的空间并不是很大,但破解的时间窗口很小,而且就算这次破解了,也会很快失效。现在使用的6位数字密码和半分钟间隔,主要还是考虑到人类操作的方便性考虑的。其实这个算法可以很方便的扩展成为更安全的形式,如字母密码,更长位数等等。

从应用角度,GOTP的安全性还体现在“系统隔离”。用户使用的验证器,对于应用系统本身而言其实是一个“外部”系统,在验证匹配的时候,两者只靠逻辑和数学关系关联。这种分离系统的结构,无疑提高了攻击和破解的难度。

集成应用流程

基于以上示例代码,在真实的应用场景中的集成应用流程大致如下:

  • 某个应用需要和中心服务器集成时,需要先配置共享密钥
  • 应用进行数据请求或者传输时,会计算并附加当前的Token(getToken方法)
  • 接收端检查Token,确认请求的合法(checkToken方法)
  • 接收端进行后续操作
  • 如果出现错误,接收端应当响应或者通知认证错误
  • 可选信息的签名和验证

对于用户使用的管理客户端程序,如果对安全性要求比较高,可以采用下列集成应用流程:

  • 在服务端生成并配置管理功能共享密钥
  • 在用户的认证器,如Google Authticatior 程序中配置相同的密钥
  • 当用户在使用管理工具,特别是命令行工具时,需要在每次操作中,检查并输入当前OTP
  • 管理程序会将OTP进行编码,并作为请求参数,提交给服务端
  • 服务端检查Token,并进行后续操作
  • 如果认证错误,服务端应当响应认证错误
  • 可选信息的签名和验证

问题和思考

本技术方案的主要目标并不是提供最高的安全性,而是平衡安全性和实现的简单方便。特别是要考虑到用户和系统共同参与的过程(比如用户使用客户端程序进行业务管理操作等场合)。

如果需要更好的安全性,无疑应当使用公钥加密的方案。但那样会带来很多算法兼容、第三方程序引用、公钥的管理等方面的问题。开发者需要进行选择和权衡。

另外,如果仅考虑到系统之间的集成安全问题,不需要考虑和谷歌认证器的兼容性,可以简单的通过更换hash算法,增加密码长度,减少时间片长度等方式看,来增加认证的安全性。

小结

本文提出了一种基于OTP的系统间集成认证,包括用户管理工具和系统之间认证的技术方案。和传统方案相比,具有实现和架构简单,安全性好,扩展性强,应用场景丰富等特点。