java集成动态令牌 动态令牌有什么用_服务器

上图是中国银行的动态口令牌。中行动态口令每60秒随机更新一次,密码显示为6位数字。大家有没有想过,这种设备是不具备联网功能的,那这个随着时间一直改变的动态口令密码,当你在手机app中输入后,银行又是怎么知道你这个动态口令是正确的呢?

我们先看看我们为什么需要动态口令,这就得从双因素验证说起了。我们一般可以通过三种不同类型的证据来证明一个人的身份:

  1. 秘密信息: 只有用户知道的信息,比如密码。
  2. 私人物品: 比如身份证,银行卡,钥匙,手机等。
  3. 生理特征: 用户的遗传特征,比如指纹、人脸、虹膜等。

那么双因素认证,就是同时认证以上的两种因素,来确定一个人的身份。举个例子,你用手机银行给他人的银行卡转账,那么你需要输入你的银行密码和短信验证码;你用到ATM机去转账,你需要你的银行卡和密码。那有人会说,我支付宝和微信转账就只用支付密码就能转账,其实背后并不是这么简单,一般这些金融公司会根据你的操作类型和金额大小,用背后强大的风控系统来判断你需要验证哪些因素,可感知的,有支付密码,验证码,人脸识别,手机的指纹识别,iPhone的face id等。感知不到的还有软动态口令,类似上图的应该的物理动态口令,你的app会像物理动态口令一样,每隔30秒或60秒,就生成一个动态口令码,这个动态口令是根据你的app上的动态口令密钥生成的,这个密钥会在你登录成功后下发到你的app中,当然登录时候经过了双因素验证确保是你本人在使用手机。

下图是第三方的软动态口令Google Authenticator OTP,这个口令一样是根据时间在改变的,OTP就是一次性密码(One Time Password)的缩写。这种软动态口令在国外用的会比较多。

java集成动态令牌 动态令牌有什么用_有效时间_02

有了以上的铺垫,我们回到我们一开始的问题,动态口令是怎么离线生成的呢?

首先,服务器会生成一个密钥,这个密钥会通过安全的方式保存到用户的手机,可以是用户扫码绑定,也可以是验证用户身份后加密下发到用户的手机中,这时候,用户和服务器就有了同一把密钥。这个密钥是和手机绑定的,如果用户更换手机,那么旧密钥就会失效。同样的,上面提到的中国银行的动态口令设备就是在设备上保存着和服务器中一样的密钥,然后这个动态口令设备会在银行网点交到用户的手中。

接着,在需要用到动态口令的时候,手机端或者动态口令设备,会使用密钥和当前时间计算出来一个哈希值,再通过这个哈希值算出个6位数字的密码,有效时间是30秒或者60秒,用户在有效时间内将这个哈希值提交给服务器,然后服务器也会用同样的密钥和当前时间计算出来一个哈希值,比计算出6位数字的密码,比对两个6位密码,如果相同则说明动态口令正确。

那这个有效时间是怎么实现的呢,其实也很简单,我简单举个例子大家就明白了,以有效时间为60秒为例,比如说现在是1900年1月1日 0时0分0秒,那么我们就让0时0分0秒到0时1分0秒的时间内生成的时间值为0,0时1分0秒到0时2分0秒的时间内生成的时间值为1,0时2分0秒到0时3分0秒的时间内生成的时间值为2,依次类推。有技术背景的朋友相信看到下面计算也能很快明白,时间值 = Date.now() / 1000 / 60 。

上面的这个算法,其实有个官方的名字,叫TOTP (Time-Based One Time Password)。另外还有一个算法叫HOTP(HMAC-Based One Time Password),是通过某个事件的特定次序及相同密钥作为输入来进行哈希计算得到密钥,每次验证后,事件的计数器都会加一