盘点认证协议:普及篇之OTP和短信认证方式

总文档 :文章目录
Github : github.com/black-ant

  • 纯约束型协议 : OAuth , SAML , OIDC , CAS ,LTPA
  • 服务器类协议 : RADIUS , Kerberos , ADFS
  • 认证方式类 : OTP , 生物认证 (人脸 , 声纹 , 指纹)
  • 认证服务器(附带) : AD , LDAP , ADFS

这一篇主要是闲谈一下 OTP 和短信验证码 ,他们2者的逻辑其实是一致的

一 . OTP 认证

1.1 什么是 OTP 认证

OTP 在很多地方都能找到它的痕迹 , 例如支付宝的6位随机密码 , 其实也是一种很复杂的 OTP 方式 .

OTG 是动态密码 ,每个令牌有不同的ID 与其绑定 ,令牌根据该 ID 和当前 时间 计算出 6位 随机代码 ,服务端 会根据 该 ID 生成随机码 ,如果相同则判断正确,

OTP 安全的核心在于密钥 , 每个人通过对应账户生成的密钥是不同的 . 当他们用同一个算法加密时 , 会生成不同的随机密码 .

Goole 身份验证器案例 :

image.png

可以看到 , 其中有三个输入条件 : 账户名 + 密钥 + 密钥类型 , 这就带出了 OTP 的多种类型

1.2 OTP 类型

OTP类型 :

  • 时间性 : 以时间为参数
  • 事件性 : 以次数为参数
  • 挑战数 : 以异步挑战数作为参数 ,即服务端下发 挑战码

根据不同的类型 , OTP 又提供了多种不同的 OTP 算法 ,主要有2种 :

  • TOTP(Time-Based One-Time Password,基于时间的一次性密码)
  • HOTP(HMAC-based One-Time Password,一种基于HMAC的一次性口令算法)

我们来看一下他们的细节 :

OTP 算法 :

// 计算公式 : OTP(K,C) =Truncate ( HMAC - SHA - 1 ( K , C ) )

K : 密钥串 ,ID
C :参数
HMAC-SHA-1 : 使用SHA-1做HMAC
Truncate  :截取加密后的串,并取加密后串的哪些字段组成一个数字 
复制代码

HMAC-SHA-1 模式 :

  1. HMAC-SHA-1加密后的长度得到一个20字节的密串
  2. 取这个20字节的密串的最后一个字节,取这字节的低4位,作为截取加密串的下标偏移量
  3. 按照下标偏移量开始,获取4个字节,按照大端方式组成一个整数
  4. 截取这个整数的后6位或者8位转成字符串返回

TOTP 算法

// TOTP : TOTP只是将其中的参数C变成了由时间戳产生的数字。
C = (T - T0) / X;    
T  :  当前时间戳
T0 :  取值为 0
x :  步数 ,多久参数一个动态密码
复制代码

TOPT_Algorithm.png

HOTP 算法

详情参考 : HOTP和TOTP算法图解 @ www.jianshu.com/p/a7b900e8e…

HTOP 是基于计数器的算法 , 服务端和客户端共用一个密钥 , HOTP 的问题在于怎么保证计数器的同步,

一句话说明: 每次请求和验证 HOTP 时,移动因子将根据计数器递增。生成的代码是有效的,直到您主动请求另一个代码并由身份验证服务器进行验证。每次验证代码和用户获得访问权限时,OTP 生成器和服务器都会同步。

对于 HOTP,通过下图我们已经看到输入算法的主要有两个元素,一个是共享密钥,另外一个是计数。在 RFC 算法中用一下字母表示:

K 共享密钥,这个密钥的要求是每个 HOTP 的生成器都必须是唯一的。一般我们都是通过一些随机生成种子的库来实现。
C 计数器,RFC 中把它称为移动元素(moving factor)是一个 8个 byte的数值,而且需要服务器和客户端同步。

另外一个参数比较好理解,Digit 表示产生的验证码的位数

最后两个参数可能暂时不好理解,我们先放在这,等用到在解释

T 称为限制参数(Throttling Parameter 表示当用户尝试 T 次 OTP 授权后不成功将拒绝该用户的连接。

s 称为重新同步参数(Resynchronization Parameter 表示服务器将通过累加计数器,来尝试多次验证输入的一次性密码,而这个尝试的次数及为 s。该参数主要是有效的容忍用户在客户端无意中生成了额外不用于验证的验证码,导致客户端和服务端不一致,但同时也限制了用户无限制的生成不用于验证的一次性密码。

OTP_algorithm_steps.png

1.3 OTP 超前步数问题及方案


> 1 服务端的次数落后客户端的次数 , 服务端会匹配多次 , 以达到和客户端同步的次数 ,匹配成功
> 2 服务端超前客户端 

// 以下图存在bug , 服务端超前于客户端时,讲不在能验证!!!!!!!!!!!!!
// 解决方案 : 服务器的值应该只能在成功后进行递增 , 只有用户登录成功后 , 才可以更新用户的计数
// 服务端会允许一定次数的计数器 ,但是如果超过限度 , 程序会报错

复制代码

HOTP_verification_process.png

1.4 OTP 总结

OTP 有其便利性 , 可以避免繁多的密码问题 , 但是这意味着需要一个 Client 端去实现一套 OTP 逻辑 , 相对于短信验证码 , 它显得更加复杂 , 问题也会更多 . 但他有存在的必要

不过相对于认证 , 如果作为支付宝那样的支付方式 ,其实也是很不错的选择 .

局限和优势 :
虽然两者都比完全不使用 MFA 安全得多,但是 HOTP 和 TOTP 都有其局限性和优势。

  • TOTP (两种技术中较新的一种)易于使用和实现,但是基于时间的元素确实有可能出现时间漂移(密码创建和使用之间的滞后)。如果用户没有立即输入 TOTP,有可能在他们输入之前就过期了。因此,服务器必须考虑到这一点,并使用户可以轻松地再次尝试,而不必自动锁定它们。

  • HOTP 没有基于时间的限制,所以它比较用户友好,但是可能更容易受到穷举法的影响。这是因为 HOTP 有效的窗口可能比较长。某些形式的 HOTP 通过在其代码中添加一个基于时间的组件来解释这一漏洞,这在一定程度上模糊了这两种类型 OTP 之间的界限。

二 . 短信验证码

为什么有了短信验证码 , 还会有OTP ?

现阶段的黑客技术种已经找到了截获这些短信代码的创造性方法,无论是通过SIM 卡欺诈还是其他类型的黑客手段,帮助他们获取你的短信。

  • 也有可能联系你的供应商,将你的电话号码转移到一个新的电话上
  • 利用用于漫游的连接系统 SS7的问题拦截网络上的 SMS 消息

虽然基于 sms 的 MFAs 可能比没有 MFA 要好,但是它们的安全性比手机上的认证应用程序或者使用密钥代码生成器要差得多

这就意味着短信验证码其实并不是绝对安全 (PS : 破解也存在局限性 ,没有违规操作 ,也没有可乘之机)

相对于首次登录就使用验证码 , 很多短信验证码场景是在首次认证的二次认证(MFAS)后进行使用 ,但是其实这也只是多加了一层

**因为这个原因 , 所以才需要 OTP 来完成更安全的功能 . **

总结和感谢

文章部分参考于 www.jianshu.com/p/a7b900e8e… , 想看更多的可以看看原博主的文章

这篇文章不算长 , 毕竟 OTP 的东西其实就那么点 , 现阶段已经有很多现成的包实现了相关的代码 ,其实复用是没有关系的 , 因为只要密钥不公布 , 问题都不大 .

包括 Google Auth , 他们使用的都是同一套算法 , 我们一般会在用户创建时就为其特定生成一个密钥 , 通过保密的途径提供给用户 ,自行录入即可.