2FA双因子认证之OTP算法

概述

2 Factor Authentication简称2FA,双因子认证是一种安全密码验证方式。区别于传统的密码验证,由于传统的密码验证是由一组静态信息组成,如:字符、图像、手势等,很容易被获取,相对不安全。2FA是基于时间、历史长度、实物(信用卡、SMS手机、令牌、指纹)等自然变量结合一定的加密算法组合出一组动态密码,一般每60秒刷新一次。不容易被获取和破解,相对安全。

TOTP/HOTP作为其中的一种(实际是两种,不过其中一个是变种,这里当作一种)算法,目前已经用于大多数网站,例如GitHub、阿里云等;

HOTP

算法考虑因素

  • 算法必须是基于序列或者计数的;
  • 该算法在硬件上应该是经济的(对硬件要求不高);
  • 该算法必须适用于不支持任何数字输入的令牌,但也可以用于更复杂的设备,例如PIN-pads;
  • 用户必须能轻松读取和输入令牌上显示的值,这需要HOTP值长度合理;HOTP应该至少为6位,并且仅包含数字,这样可以方便的在受限设备上输入;
  • 必须具有用户友好的机制用来重新同步计数器;
  • 该算法必须使用强共享密钥,共享密钥的长度必须至少为128位,建议160位;

符号定义

  • 如果s表示字符串,那么 | s | 表示他的长度,如果s表示数字,那么 | s | 表示他的绝对值;
  • 如果s表示字符串,那么s[i]表示他的第i位(从0开始);
  • StToNum(String to Number)函数表示将入参转换为数字,入参是数字的二进制表示,例如 StToNum(110) = 6
  • C:8byte计数器,移动因子(moving factor),这个counter必须能在HOTP客户端与服务端同步;
  • K:客户端与服务端共享密钥,每个HOTP生成器都有一个不同且唯一的密钥;
  • T:T次校验失败后服务器将拒绝该用户;
  • s:服务器将尝试通过s个连续的计数器值进行验证;
  • Digit:HOTP值的位数,系统参数;

算法详解

算法定义如下:

HOTP(K, C) = Truncate(HMAC-SHA-1(K, C))

算法说明:

要产生HOTP值,要经过下面三个步骤:

  • 生成HMAC-SHA-1值HS = HMAC-SHA-1(K, C);HS是20byte长的String;
  • 使用HS生成4byte长的String Sbits = DT(HS),DT函数在后边定义,返回一个31bit的String;
  • 计算HOTP值,Snum = StToNum(Sbits);return D = Snum mod 10^Digit;

Truncate函数就是执行步骤2和步骤3,即动态截断,动态截断技术是从20byte的HMAC-SHA-1结果中提取4byte

DT函数定义:DT(String): // String = String[0]….String[19],入参的长度是20byte,因为HMAC-SHA-1的结果长度是20byte;

  • OffsetBits表示String[19]的低4位;
  • Offset = StToNum(OffsetBits);PS: 因为OffsetBits只有4位,所以Offset的范围是0 - 15;
  • P = String[Offset]…String[Offset+3];
  • return P的低31位(这里返回31位而不是32位的原因是因为最高位在有符号数和无符号数上解释是不一样的,可能会造成混淆,而屏蔽掉最高位可以消除歧义)

TOTP

概述

TOTP算法实际上是HOTP算法的一个变种,,HOTP算法中定义了一个8byte计数器C,需要能在服务器和客户端同步,但是没有定义具体如何实现C,而TOTP则是进一步详细定义了如何实现这个8byte的计数器C,TOTP中使用时间引用(time reference)和时间步长(time step)派生的值作为C值,同时TOTP中可以使用HMAC-SHA-256或者HMAC-SHA-512来替换HMAC-SHA-1

算法考虑因素

设计TOTP算法时必须要考虑如下几个因素:

  • prover(例如令牌、软令牌,指的就是用户使用的某种客户端)和verifier(验证者,服务器端)能够获取比较准确的Unix时间(即从UTC 1970年1月1日午夜以来经过的秒数);
  • prover和verifier必须具有相同的secret或者知道如何通过共享secret推导出secret;
  • 算法必须使用HOTP作为关键构建模块;
  • prover和verifier必须使用相同的时间步长(time step);
  • 每个prover必须有一个唯一的secret(key);
  • 密钥(keys、secret)应该随机生成或者使用密钥生成算法生成;
  • 密钥(key)可以存储在防篡改设备中,应该是防止未授权的访问和使用;

算法详解

TOTP算法定义:

TOTP = HOTP(K, T)

详细说明:

  • 其中T = (Current Unix Time -T0) / X ,这里计算中结果默认向下取整,丢弃小数部分;
  • 该算法的实现必须支持时间值T在2038年之后大于32位整数的情况(可以通过调整X和T0的值来实现,或者到时候使用其他解决方案);
  • 该算法的安全性取决于HOTP算法的安全性,分析表明,对于该算法的最佳破解手段就是暴力破解(即遍历);
  • 时间步长不应该太长,也不应该太短,太长的话会使攻击变得简单(攻击者有更多时间实施攻击),太短的话会对性能有影响;因为verifier不知道prover使用的时间戳,在经过网络延迟以及其他延迟后,可能导致prover使用的时间戳落入的步长区间与verifier使用的时间戳落入的步长区间不一致,导致最终的T值不一致,此时我们可以允许verifier多使用一个步长作为延迟,但是不建议更多,因为这会间接导致实际的时间步长变长,使攻击变得简单;

参考文档

  • RFC6238

参考JS实现


class TOTP {// 步长#X;// 初始时间偏移,单位秒#T0;// hmacSha1算法#hmacSha1;/*** 构造器* @param key 密钥,8位数字数组,必传* @param X 步长,默认30* @param T0 初始时间偏移,单位秒,默认0*/constructor(key, X, T0) {if (key == null) {throw "密钥不能为空";}if (!(key instanceof Array)) {throw "密钥必须是数组";}if (X == null || X <= 0) {X = 30;}if (T0 == null || T0 < 0) {T0 = 0;}this.#X = X;this.#T0 = T0;this.#hmacSha1 = new HMAC(new SHA1(), 20, 64);this.#hmacSha1.init(key);}/*** 校验给定的TOTP value是否合法* @param value 给定的TOTP value* @returns {boolean} true表示合法*/verify(value) {if (value == null || typeof value != "string") {throw "参数错误,参数必须是string; " + value == null ? "null" : typeof value;}return this.generateTOTPValue(value.length) === value;}/*** 生成TOTP value* @param returnDigits 结果长度,默认6* @param unixTime Unix日期,默认取当前时间* @returns {string} TOTP value*/generateTOTPValue(returnDigits, unixTime) {if (returnDigits == null || returnDigits <= 0) {returnDigits = 6;}if (unixTime == null || unixTime <= 0) {unixTime = Math.round(new Date().getTime() / 1000);}let T = Math.floor((unixTime - this.#T0) / this.#X);let data = [];data[0] = 0;data[1] = 0;data[2] = 0;data[3] = 0;data[4] = T >>> 24 & 0xff;data[5] = T >>> 16 & 0xff;data[6] = T >>> 8 & 0xff;data[7] = T >>> 0 & 0xff;let hash = this.#hmacSha1.doFinal(data);let offset = hash[hash.length - 1] & 0xf;let binary = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16)| ((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff);let otp = binary % Math.pow(10, returnDigits);let result = otp.toString();while (result.length < returnDigits) {result = "0" + result;}return result;}}/** TOTP使用示例,注意,TOTP依赖与HMAC算法,HMAC算法请参考前一篇文章,前一篇文章中有HMAC算法的JS示例代码*/
// 使用示例:指定步长位30,偏移为0
let totp = new TOTP([0, 0, 0, 0], 30, 0);
// 生成6位的TOTP value
let totpValue = totp.generateTOTPValue(6);
console.log(totpValue);

联系我

  • 作者微信:JoeKerouac
  • 微信公众号(文章会第一时间更新到公众号):代码深度研究院
  • GitHub:https://github.com/JoeKerouac

2FA双因子认证之OTP算法相关推荐

  1. 宁盾目录成功对接Coremail邮箱,为其提供LDAP统一认证和双因子认证

    近日,宁盾与 Coremail 完成兼容适配,在 LDAP 目录用户同步.统一身份认证及双因子认证等模块成功对接.借此机会,双方将加深在产品.解决方案等多个领域的合作,携手共建信创合作生态,打造信创 ...

  2. 将钉钉、飞书、企业微信账号同步到Synology群晖NAS,并开启LDAP双因子认证

    用户使用钉钉.飞书.企业微信账号即可登录群晖 Synology NAS 等LDAP协议应用,账号的创建.删除.变更都会自动同步给下游LDAP应用,这意味着账号管理流程缩短了一倍.而流程如此高效,秘密就 ...

  3. 用双因子认证2FA替换Google authenticator谷歌令牌,助力准上市公司实现等保安全审计

    21世纪初,某人力资源科技公司试水HR SaaS赛道,以大客户为目标客群,持续深耕,稳扎稳打,如今已是一家专门为中大型企业提供一体化HR SaaS及人才管理产品/解决方案的头部企业.其产品覆盖了从员工 ...

  4. 什么是双因子认证(2FA)

    双因子验证(2FA),有时又被称作两步验证或者双因素验证,是一种安全验证过程.在这一验证过程中,需要用户提供两种不同的认证因素来证明自己的身份,从而起到更好地保护用户证书和用户可访问的资源.双因子验证 ...

  5. 指纹安全系统--双因子认证(2FA)解决方案

    双因子认证(2FA)解决方案 方案应用背景 应用需求 方案阐述 一.方案特点 二.方案设计 三.方案组成 四.环境要求 方案应用背景 随着企业日益发展的需求,企业IT管理面临越来越大的压力与挑战.得益 ...

  6. 九州云腾双因素认证系统_“等保2.0”新标准落地 双因子认证(2FA)成标配...

    2019年5月13日,国家标准新闻发布会正式发布网络安全等级保护制度2.0标准(以下简称"等保2.0"),新标准将于2019年12月1日开始实施,这意味着"等保2.0&q ...

  7. 网神防火墙如何启用双因素/双因子认证(2FA/MFA)身份认证

    网神防火墙基于多核处理器架构和自主开发的新一代多核并行操作系统 SecOS,完整实现了状态检测包过滤/应用代理防火墙.IPSec VPN/SSL VPN.抗DDoS攻击.深度内容检测.入侵检测防护.带 ...

  8. 双因子认证!这4种身份认证方式你都了解吗?

    双因子认证的小科普 前几天公司里忽然出现了一个陌生人,坐在甄梵仁的位子上. 正当我打算和他打个招呼时,他却脱口而出:"贾正经,好久不见!" 这声音不是甄梵仁的吗?他整容了?? 这整 ...

  9. 【最佳实践】双因子认证在行云管家中的应用实践

    一.什么是双因子认证 双因子认证,也称为双因素认证,是指使用两种独立不相干的证据来证明当前用户身份.通常而言,我们登录一个IT系统的首选认证方式是用户名和密码,但显然,单靠用户名和密码是不够的,我们还 ...

最新文章

  1. eclipse中使用javap分析java代码备忘
  2. 数据库连接jdbc理解
  3. 所有子序列的逆序对总和_一个数字的所有子串的总和
  4. git笔记之解决eclipse不能提交jar等文件的问题
  5. springboot - 应用实践(N)使用springboot内置的@Scheduled
  6. Boost C++ 智能指针
  7. Spine_图片显示出错的处理方法
  8. 3D贴图绘制软件Substance 3D Painter 2022中文版
  9. SECS Message解析说明
  10. [Error] invalid operands to binary ^ (have ‘double‘ and ‘float‘)
  11. python爬虫二十三:使用fiddler抓取app数据(三)
  12. SAP中寄售结算规则及要点分析
  13. Mac上一款简单实用音频剪辑工具——QuickTime Player
  14. JS时间的计算,剩余时间的计算
  15. 广西行政村数据shp_广西自治区乡镇行政区划数据 精度1:10万
  16. Web安全工具—Sqlmap常用命令和参数(持续更新)
  17. Linux下安装oracle11.2.0.4
  18. iOS VIPER 架构解读
  19. 数据挖掘之-简单属性之间的相似度和相异度
  20. 6年Java老鸟聊聊新人到底要不要学Java,从事互联网《打工人的那些事》

热门文章

  1. c语言程序设计对口升学,2017年对口升学计算机专业试题含答案
  2. 调试并修理垂起固定翼(VTOL)
  3. 欧拉方法python代码实现
  4. 新版知乎登录request登录(2)(类编程)
  5. 一个栈的输入序列为1 2 3 4 5 的出站顺序的理解
  6. 织梦html标题怎么改,织梦网站seo优化技巧-改栏目名称seo标题即可
  7. 计算机图形学 ———— 扫描线多边形填充算法 (讲解)
  8. Pytorch实现Top1准确率和Top5准确率
  9. 神策数据通过首批 MA(营销自动化平台)基础能力评测
  10. 林斤澜:温故知新——读《故事新编》