安全开发:身份认证方案之 Google 身份验证器和基于时间的一次性密码 TOTP 算法

本文主要是介绍安全开发:身份认证方案之 Google 身份验证器和基于时间的一次性密码 TOTP 算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 参考资料在文末注明,如本文有错漏欢迎评论区指出👏

目前很多应用都逐步采用了双因子认证或者说MFA认证方案,因此本文介绍一下背后的机制和TOTP算法原理。使用TOTP算法,只要满足两个条件:1)基于相同的密钥;2)时钟同步;只需要事先约定好密钥,TOTP算法就可以保证校验段和被校验端具有相同的输出。

OTP

在介绍 TOTP 算法前,先介绍一下 OTP 算法。OTP,One Time Password,又称一次性口令、一次性密码、动态密码、单次有效密码。OTP 基于专门的算法每隔一定的时间间隔生成一个不可预测的随机数字组合。OTP密码有效期仅在一次会话或者交易过程中,因此不容易受到重放攻击。OTP分为计次使用和计时使用两种,计次使用的OTP产出后,可在不限时间内使用。计时使用的 OTP 需要设置密码有效时间,从30秒到两分钟不等,而 OTP 在进行认证之后即废弃不用,下次认证必须使用新的密码,降低了不经授权访问限制资源可能性。

OTP密码进一步分为:

  • HOTP:HMAC-based One-Time Password ,基于 HMAC 算法的一次性密码。事件同步,通过某一特定的事件次序及相同的种子值作为输入,通过 HASH 算法运算出一致的密码。
  • TOTP:Time-based One-Time Password写,基于时间戳算法的一次性密码。 时间同步,基于客户端的动态口令和动态口令验证服务器的时间比对,一般每 30 秒产生一个新口令,要求客户端和服务器能够十分精确的保持正确的时钟,客户端和服务端基于时间计算的动态口令才能一致。

计算 OTP 串的公式:OTP(K,C) = Truncate(HMAC-SHA-1(K,C))
K 表示秘钥串;C 为随机数;HMAC-SHA-1 表示使用 SHA-1 做 HMAC;Truncate 表示怎么截取加密后的串,并取加密后串的哪些字段组成一个数字;

对 HMAC-SHA-1 方式加密来说,Truncate 实现如下:
HMAC-SHA-1 加密后的长度得到一个 20 字节的密串;取这个 20 字节的密串的最后一个字节,取这字节的低 4 位,作为截取加密串的下标偏移量;按照下标偏移量开始,获取4个字节,按照大端方式(符合人类习惯的形式,比如 0x12 34 , 0x12 存放在低地址,大端即大端在前/高位在低地址存放的意思)组成一个整数;截取这个整数的后 6 位或者 8 位转成字符串返回。

TOTP 将其中的参数 C 变成了由时间戳产生的数字:C = (T - T0) / X; T 表示当前 Unix 时间戳:T0 一般取值为 0,也就是 1970 年 1 月 1 日。X 表示时间步数,也就是说多长时间产生一个动态密码,这个时间间隔就是时间步数 X,系统默认是 30 秒;

一个信息系统要集成 OTP 的认证方式,需要完成以下的工作:
1、开发手机令牌
2、开发认证的服务端,服务端需要完成令牌种子生成、令牌种子分发、动态口令生成等功能。
3、在OTP认证的服务端需要将业务系统的用户与分发的令牌建立关联,这样才能完成最终的登录验证。

TOTP


TOTP 算法(Time-based One-time Password algorithm) 即基于具有时间戳计数器的 OTP。通过定义纪元(T0)的开始并以时间间隔(TI)为单位计数,将当前时间戳变为整数时间计数器(TC)。TOTP 实现可以使用 HMAC-SHA-256 或HMAC-SHA-512 (基于 SHA-256 或 SHA-512)函数来实现,而不是 HOTP 计算中的 HMAC-SHA-1 函数【注:SHA1 存在 HASH 碰撞】。

TOTP 密码生成过程

  1. 初始化:用户在服务提供商(如 Google 等)注册账户时,服务提供商(服务器)会为用户生成一个 密钥(Secret Key) 并保存在数据中。然后把这个密钥会以某种方式(通常是 二维码 )分享给用户,用户将其添加到(通过扫码)自己的身份验证器应用(如 Google Authenticator、Microsoft Authenticator)中。
  2. 生成 TOTP:身份验证器应用会按照固定的时间间隔(常见的是 30 秒)使用 HMAC-SHA1 算法,使用当前的时间戳和在初始化步骤中获取的密钥,生成一个新的一次性密码,这个密码通常是一个 6 位数字(但也可能更长或更短)。
  3. 验证 TOTP:当用户尝试登录或执行需要验证的操作时,会被要求提供当前的一次性密码。用户从自己的身份验证器应用中获取这个密码,并输入到服务提供商的网站或应用中。服务提供商会使用同样的算法和密钥,以及当前的时间戳,生成一个一次性密码,并将其与用户提供的密码进行比较。如果两个密码匹配,那么用户的身份就被认为已经验证。

基于 Node.js 实现支持 Google 身份验证器的 TOTP 算法

import { Secret, TOTP } from 'otpauth';// 生成密钥
const secret = Secret.fromUTF8('your_secret_key'); // 生成TOTP实例
const totp = new TOTP({secret,issuer: 'Example',label: 'alice@example.com'  
});// 生成token
const token = totp.generate();  // 30s
console.log('totp token:')
console.log(token);// 验证token
const isValid = totp.validate({token,window: 1  // 一个窗口为一个 period
});if(isValid !== null) {console.log('Valid token'); 
} else {console.log('Invalid token');
}// 转成uri格式
const uri = totp.toString(); 
console.log(uri);

Reference

  1. Google身份验证器、基于时间的一次性密码 (TOTP)算法
  2. OTP概念及实现原理简析
  3. 基于时间的一次性密码 TOTP 详解
  4. 密码学I:密码系统、OTP密码和密码的安全性
  5. 一文搞懂 OTP 双因素认证
  6. 使用 Golang 实现基于时间的一次性密码 TOTP
  7. 基于 Node 实现 TOTP:Otplib

这篇关于安全开发:身份认证方案之 Google 身份验证器和基于时间的一次性密码 TOTP 算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/483996

相关文章

使用Python开发一个带EPUB转换功能的Markdown编辑器

《使用Python开发一个带EPUB转换功能的Markdown编辑器》Markdown因其简单易用和强大的格式支持,成为了写作者、开发者及内容创作者的首选格式,本文将通过Python开发一个Markd... 目录应用概览代码结构与核心组件1. 初始化与布局 (__init__)2. 工具栏 (setup_t

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各

Spring Shell 命令行实现交互式Shell应用开发

《SpringShell命令行实现交互式Shell应用开发》本文主要介绍了SpringShell命令行实现交互式Shell应用开发,能够帮助开发者快速构建功能丰富的命令行应用程序,具有一定的参考价... 目录引言一、Spring Shell概述二、创建命令类三、命令参数处理四、命令分组与帮助系统五、自定义S

SpringSecurity JWT基于令牌的无状态认证实现

《SpringSecurityJWT基于令牌的无状态认证实现》SpringSecurity中实现基于JWT的无状态认证是一种常见的做法,本文就来介绍一下SpringSecurityJWT基于令牌的无... 目录引言一、JWT基本原理与结构二、Spring Security JWT依赖配置三、JWT令牌生成与

Java中Date、LocalDate、LocalDateTime、LocalTime、时间戳之间的相互转换代码

《Java中Date、LocalDate、LocalDateTime、LocalTime、时间戳之间的相互转换代码》:本文主要介绍Java中日期时间转换的多种方法,包括将Date转换为LocalD... 目录一、Date转LocalDateTime二、Date转LocalDate三、LocalDateTim

Python从零打造高安全密码管理器

《Python从零打造高安全密码管理器》在数字化时代,每人平均需要管理近百个账号密码,本文将带大家深入剖析一个基于Python的高安全性密码管理器实现方案,感兴趣的小伙伴可以参考一下... 目录一、前言:为什么我们需要专属密码管理器二、系统架构设计2.1 安全加密体系2.2 密码强度策略三、核心功能实现详解

SpringSecurity6.0 如何通过JWTtoken进行认证授权

《SpringSecurity6.0如何通过JWTtoken进行认证授权》:本文主要介绍SpringSecurity6.0通过JWTtoken进行认证授权的过程,本文给大家介绍的非常详细,感兴趣... 目录项目依赖认证UserDetailService生成JWT token权限控制小结之前写过一个文章,从S

golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法

《golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法》:本文主要介绍golang获取当前时间、时间戳和时间字符串及它们之间的相互转换,本文通过实例代码给大家介绍的非常详细,感兴趣... 目录1、获取当前时间2、获取当前时间戳3、获取当前时间的字符串格式4、它们之间的相互转化上篇文章给大家介

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA