专栏首页业余草业余草双因素认证(2FA)教程

业余草双因素认证(2FA)教程

所谓认证(authentication)就是确认用户的身份,是网站登录必不可少的步骤。 密码是最常见的认证方法,但是不安全,容易泄露和冒充。

越来越多的地方,要求启用双因素认证(Two-factor authentication,简称 2FA)。本文介绍它的概念和实现方法。

我的博客:CODE大全www.codedq.net业余草www.xttblog.com爱分享www.ndislwf.comifxvn.com

双因素认证的概念

一般来说,三种不同类型的证据,可以证明一个人的身份。

  • 秘密信息:只有该用户知道、其他人不知道的某种信息,比如密码。
  • 个人物品:该用户的私人物品,比如身份证、钥匙。
  • 生理特征:该用户的遗传特征,比如指纹、相貌、虹膜等等。

这些证据就称为三种"因素"(factor)。因素越多,证明力就越强,身份就越可靠。 双因素认证就是指,通过认证同时需要两个因素的证据。 银行卡就是最常见的双因素认证。用户必须同时提供银行卡和密码,才能取到现金。

双因素认证方案

常用的双因素组合是密码 + 某种个人物品,比如网上银行的 U 盾。用户插上 U 盾,再输入密码,才能登录网上银行。

但是,用户不可能随时携带 U 盾,手机才是最好的替代品。密码 + 手机就成了最佳的双因素认证方案。

国内的很多网站要求,用户输入密码时,还要提供短消息发送的验证码,以证明用户确实拥有该手机。

但是,短消息是不安全的,容易被拦截和伪造,SIM 卡也可以克隆。已经有案例,先伪造身份证,再申请一模一样的手机号码,把钱转走。 因此,安全的双因素认证不是密码 + 短消息,而是下面要介绍的 TOTP。

TOTP 的概念

TOTP 的全称是"基于时间的一次性密码"(Time-based One-time Password)。它是公认的可靠解决方案,已经写入国际标准 RFC6238。

它的步骤如下。 第一步,用户开启双因素认证后,服务器生成一个密钥。 第二步:服务器提示用户扫描二维码(或者使用其他方式),把密钥保存到用户的手机。也就是说,服务器和用户的手机,现在都有了同一把密钥。

注意,密钥必须跟手机绑定。一旦用户更换手机,就必须生成全新的密钥。 第三步,用户登录时,手机客户端使用这个密钥和当前时间戳,生成一个哈希,有效期默认为30秒。用户在有效期内,把这个哈希提交给服务器。

第四步,服务器也使用密钥和当前时间戳,生成一个哈希,跟用户提交的哈希比对。只要两者不一致,就拒绝登录。

我的博客:CODE大全www.codedq.net业余草www.xttblog.com爱分享www.ndislwf.comifxvn.com

TOTP 的算法

仔细看上面的步骤,你可能会有一个问题:手机客户端和服务器,如何保证30秒期间都得到同一个哈希呢? 答案就是下面的公式。

TC = floor((unixtime(now) − unixtime(T0)) / TS)

上面的公式中,TC 表示一个时间计数器,unixtime(now)是当前 Unix 时间戳,unixtime(T0)是约定的起始时间点的时间戳,默认是0,也就是1970年1月1日。TS 则是哈希有效期的时间长度,默认是30秒。因此,上面的公式就变成下面的形式。

TC = floor(unixtime(now) / 30)

所以,只要在 30 秒以内,TC 的值都是一样的。前提是服务器和手机的时间必须同步。 接下来,就可以算出哈希了。

TOTP = HASH(SecretKey, TC)

上面代码中,HASH就是约定的哈希函数,默认是 SHA-1。 TOTP 有硬件生成器和软件生成器之分,都是采用上面的算法。

(说明:TOTP 硬件生成器)

(说明:Google Authenticator 是一个生成 TOTP 的手机 App)

TOTP 的实现

TOTP 很容易写,各个语言都有实现。下面我用 JavaScript 实现2fa来演示一下真实代码。 首先,安装这个模块。

$ npm install --save 2fa

然后,生成一个32位字符的密钥。

var tfa = require('2fa');

tfa.generateKey(32, function(err, key) {
  console.log(key);
});
// b5jjo0cz87d66mhwa9azplhxiao18zlx

现在就可以生成哈希了。

var tc = Math.floor(Date.now() / 1000 / 30);
var totp = tfa.generateCode(key, tc);
console.log(totp); // 683464

总结

双因素认证的优点在于,比单纯的密码登录安全得多。就算密码泄露,只要手机还在,账户就是安全的。各种密码破解方法,都对双因素认证无效。 缺点在于,登录多了一步,费时且麻烦,用户会感到不耐烦。而且,它也不意味着账户的绝对安全,入侵者依然可以通过盗取 cookie 或 token,劫持整个对话(session)。 双因素认证还有一个最大的问题,那就是帐户的恢复。

一旦忘记密码或者遗失手机,想要恢复登录,势必就要绕过双因素认证,这就形成了一个安全漏洞。除非准备两套双因素认证,一套用来登录,另一套用来恢复账户。

我的博客:CODE大全www.codedq.net业余草www.xttblog.com爱分享www.ndislwf.comifxvn.com

参考链接

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 时间管理自我管理的演讲稿

    时间管理是指通过事先规划并运用一定的技巧、方法与工具实现对时间的灵活以及有效运用,从而实现个人或组织的既定目标,EMBA、MBA等主流商业管理教育均将时间管理能...

    业余草
  • Deepfakes 换脸教程!

    这两天,ZAO 太火了。而它的背后却是 Deepfakes,作为程序员,我们很有必要来体验一把 Deepfakes !

    业余草
  • 单点登录 SSO 的前世今生

    HTTP是无状态协议,浏览器的每一次请求,服务器都会独立处理,不与之前或之后的请求产生关联,所以,任何用户都可以通过浏览器访问服务器资源。

    业余草
  • MySQL 的 join 功能弱爆了?

    关于MySQL 的 join,大家一定了解过很多它的“轶事趣闻”,比如两表 join 要小表驱动大表,阿里开发者规范禁止三张表以上的 join 操作,MySQL...

    程序员历小冰
  • 三四五线城市,移动互联网时代最后的红利

    最近,大家在大谈消费降级,其实这只是表象,真正的原因其实在于,商业巨子们都把目光投向了三四五线。从过去一年新崛起的商业新贵和创新产品来看,三四五线城市,这是移动...

    金融民工小曾
  • MySQL 的 join 功能弱爆了?

    关于MySQL 的 join,大家一定了解过很多它的“轶事趣闻”,比如两表 join 要小表驱动大表,阿里开发者规范禁止三张表以上的 join 操作,MySQL...

    程序员历小冰
  • 数据库复习题 考试题库(选择题)

    1.在数据管理技术的发展过程中,经历了人工管理阶段、文件系统阶段和数据库系统阶段。在这几个阶段中,数据独立性最高的是(   A    )阶段。

    Debug客栈
  • 故障分析 | 同一条 SQL 为何在 MariaDB 正常,MySQL 5.7 却很慢?

    爱可生 DBA 团队成员,在公司负责项目中处理数据库问题,喜欢学习技术,钻研技术问题。

    爱可生开源社区
  • JSON.stringify方法的5个秘密功能

    JSON.stringify()方法将JavaScript对象或值转换为JSON字符串。

    前端知否
  • 世纪佳缘用大数据挖掘感情骗子

      随着互联网的日益发展和人们生活节奏的不断加快,网络婚恋已经逐渐成为婚恋交友的主流方式。2月初,网信办开展“婚恋网站严重违规失信”专项整治行动,中国最大的婚恋...

    小莹莹

扫码关注云+社区

领取腾讯云代金券