TOTP 算法实现:双因素认证的基石(C/C++代码实现)

双因素认证(Two-Factor Authentication, 2FA)扮演着至关重要的角色。它像是一道额外的防线,确保即便密码被窃取,不法分子也难以轻易突破。在众多双因素认证技术中,基于时间的一次性密码(Time-Based One-Time Password, TOTP)算法因其安全性高、使用便捷而受到广泛应用。

TOTP算法是一种基于时间的一次性密码生成算法,它的核心思想是利用时间作为变化的因子来生成动态的密码。这种算法通常与用户的个人信息结合使用,如用户名或电子邮件地址,以及一个共享的秘密密钥。这个秘密密钥在用户端和服务端预先共享,是生成正确OTP的关键。

TOTP是如何工作的呢?

让我们通过一个简单的比喻来理解其原理。想象一下,你有一本只属于你和你的朋友的书,书中记载了一连串的故事,每个故事都有一个编号。每当你想要和朋友传递一个秘密信息时,你会查找当前日期对应的故事编号,并从中选取特定的段落来传递信息。在这个例子中,书就像是秘密密钥,故事编号对应于时间戳,而传递的信息则是一次性密码。

具体到TOTP算法,它使用了哈希函数(如SHA-1、SHA-256等)和时间戳。当用户想要登录系统时,用户的设备会计算当前时间与预设时间步长的差值,然后将这个差值与共享的秘密密钥一起输入到哈希函数中。哈希函数处理后输出一串较长的二进制数据,这串数据再经过模运算,得到一个较短的数字,这个数字就是OTP。用户需要在规定的时间内将这个OTP输入到验证系统中,系统同样会根据相同的秘密密钥和时间差值计算出一个OTP,并与用户提供的OTP进行比对,若两者一致,则认证成功。

在实现上,TOTP算法需要考虑到时间同步的问题。由于网络延迟或者设备时钟不准确,可能导致用户设备与服务器之间的时间有偏差。因此,TOTP算法通常会有一个时间窗口(如30秒),允许在这个时间范围内的OTP都是有效的。

TOTP的优势在于其安全性和用户体验。由于OTP是基于时间和共享秘密密钥生成的,即使黑客截获了某个时刻的OTP,它也无法在其他时间点使用,因为OTP每隔一段时间就会变化。此外,用户可以不需要记忆复杂的密码,只需拥有注册时分配的密钥(通常存储在硬件令牌或软件应用中),就可以轻松完成身份验证。

TOTP的实现

Base32编码与解码

Base32编码原理:
Base32编码是一种将二进制数据转换成32种可打印字符的编码方式。它主要用于电子邮件和URL中传输二进制数据。Base32使用A-Z的大写字母(不使用C, E, G, I, O, Q, U, V)和数字2-7来表示数据。每8位二进制数据可以编码为5个Base32字符,这意味着编码后的数据长度是原始数据的大约1.33倍。

实现Base32编码:
编码过程涉及将输入的字节数据分成5位一组,每组转换为对应的Base32字符。例如,如果输入字节是0x9A,它对应于二进制的10011010,然后将其分成两组:10011010。每组转换为Base32字符,分别是SK

实现Base32解码:
解码过程与编码相反,它将Base32字符转换回原始的字节数据。解码函数需要处理输入的Base32字符串,跳过任何非Base32字符(如填充的等号),并将每个字符转换回相应的5位二进制值。然后,这些值被重新组合成字节数据。

HMAC-SHA1算法

HMAC-SHA1基本概念:
HMAC(Hash-based Message Authentication Code)是一种消息认证码,它使用哈希算法(如SHA-1)和密钥来提供消息的完整性保护和认证。SHA-1是一种广泛使用的加密哈希函数,它可以产生一个160位(20字节)的哈希值。

在TOTP中的应用:
在TOTP中,HMAC-SHA1用于生成一个基于密钥、时间戳和算法参数的哈希值。这个哈希值随后被用来生成6位数的一次性密码。通过使用HMAC-SHA1,TOTP确保了即使密钥被泄露,生成的密码也难以被预测。

时间戳处理

时间戳的重要性:
TOTP算法依赖于时间戳来生成密码,因此时间同步至关重要。如果客户端和服务器之间的时间不同步,生成的密码可能会无效。

确保时间同步:
为了确保时间同步,可以采取以下措施:

  • 使用网络时间协议(NTP)来同步客户端和服务器的时间。
  • 在用户设备上设置时间校验机制,确保时间偏差在可接受范围内。

密码生成逻辑

从HMAC-SHA1输出中提取密码:

  1. 使用HMAC-SHA1算法和当前时间戳生成一个20字节的哈希值。
  2. 对哈希值进行处理,提取出用于生成密码的部分。具体来说,取哈希值的最后一个字节的最低4位作为索引,从这个位置开始读取接下来的4个字节。
  3. 将这4个字节视为一个整数,然后对1000000取模,得到一个6位数的密码。

生成6位数的密码:

  • 将上述步骤得到的整数转换为字符串形式,并确保它是一个6位数的密码。如果需要,可以在前面补零。

TOTP 算法实现:双因素认证的基石(C/C++代码实现)

双因素认证(2FA)作为一种增强安全性的方法应运而生。基于时间的一次性密码(TOTP)是2FA的一种实现方式,它提供了一种动态生成、一次性使用的密码,极大地提高了账户的安全性。下面实现类似Google Authenticator这样的应用程序。


void hmac(void *dest,const void *key,uint32_t key_len,const void *msg,uint32_t msg_len,void (*hash)(char *dest, const char *str, int len),uint16_t block_size,uint16_t output_size
);
typedef struct
{uint32_t state[5];uint32_t count[2];unsigned char buffer[64];
} SHA1_CTX;void sha1_transform(uint32_t state[5], const unsigned char buffer[64]);
void sha1_init(SHA1_CTX * context);
void sha1_update(SHA1_CTX * context, const unsigned char *data, uint32_t len);
void sha1_final(unsigned char digest[20], SHA1_CTX * context);
void sha1(char *hash_out, const char *str, int len);
void bytes_array_reverse(uint8_t* bytes, int size);
int bytes_array_to_int(const uint8_t* bytes, int start, int end);
int base32_decode(const uint8_t *encoded, uint8_t *result, int bufSize);
char* str_upper(char* str);
char* str_pad_left(char* str, char pad, int len);
char* str_pad_right(char* str, char pad, int len);
int int_to_str(int i, char *buf, int buf_len);void get_2fa_code(char *secret, char code[7])
{char key[20];char hash[20];int key_len;uint64_t msg;str_upper(secret);  //转换为大写以获得有效的Base32格式key_len = base32_decode((uint8_t*)secret, (uint8_t*)key, 20);           // 将机密解码为字节数组msg = time(NULL) / 30;                                                  // TOTP是HOTP,种子为30秒。bytes_array_reverse((uint8_t*)&msg, 8);                                hmac(hash, key, key_len, (uint8_t*)&msg, 8, sha1, 64, 20);              // 生成hmac哈希int offset = hash[19] & 0xF;                                            int header = bytes_array_to_int((uint8_t*)hash, offset, offset + 4);    // 从偏移量开始截断4个字节header = header & 0x7fffffff;                                           // 删除最高有效位header = header % 1000000;                                              // 生成小于7位的余数int_to_str(header, code, 7);    // 将代码转换为字符串str_pad_left(code, '0', 6);     // 从左起用0填充代码,直到代码长度为6
}
int main(int argc, char **argv)
{
...if (argc != 2) {printf("./ga [secret]\n");return (0);}get_2fa_code(argv[1], code);printf("Code :\n%s\n", code);return (0);
}

运行结果:

If you need the complete source code, please add the WeChat number (c17865354792)

总结

Google Authenticator 的核心原理是利用共享密钥和一个随时间变化的因子来生成一次性密码,从而实现第二因素的身份验证。这种方法既方便又安全,因为它不需要额外的硬件令牌,只需要用户的智能设备即可。此外,由于 OTP 是一次性的,并且随时间变化,即使黑客截获了当前的 OTP,也无法在未来的时间点使用它来冒充用户。

We also undertake the development of program requirements here. If necessary, please follow the WeChat official account 【程序猿编码】and contact me

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/16393.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【fastapi+mongodb】使用motor操作mongodb

上一篇文章,我们在电脑上安装了mongodb数据库。这篇文章,我们在fastapi后端使用motor操作mongodb 如果你还没看过上一篇文章,链接在这里:【MongoDB】安装与使用 安装 motor motor 是一个用于操作 mongodb 数据库的 python 库&a…

计算机网络 1

两台主机想通信,其实本质就是两个文件的资源交换,但是长距离的通信,面临的是很多的问题。这个时候需要通过一些方式来保证可靠性 什么是协议 这样一个例子,我是住在农村,我读高中了我需要去县里面读书。这个时候呢&…

Jupyter Lab 软件安装与使用

软件简介 Jupyter Lab 软件是一个基于web 的交互式开发环境,集成了代码编辑器、终端、文件管理器等功能,使得开发者可以在一个界面中完成各种任务。JupyterLab是Jupyter Notebook的全面升级,是一个集文本编辑器、终端以及各种个性化组件于一…

Java进阶学习笔记29——Math、System、Runtime

Math: 代表的是数学,是一个工具类,里面提供的都是对数据进行操作的一些静态方法。 示例代码: package cn.ensourced1_math;public class MathTest {public static void main(String[] args) {// 目标:了解Math类提供…

那智不二越机器人维修案例分享

那智不二越工业机器人在工业范围内广泛应用于各种生产领域。其示教器作为人机交互的重要设备,常常需要定期维护和Nachi不二越机械手示教盒修理。 【Nachi不二越机器人示教器维修步骤】 1. 关闭电源 在进行任何那智不二越机器人维修操作之前,务必确保机器…

<商务世界>《75 微课堂<茶叶(1)-质量分级>》

1 中国茶叶分级 中国的10级标准是按照茶叶的外观、香气、滋味、汤色、叶底五个方面进行评分,分别用10分制进行评分,总分为50分,得分越高,茶叶的品质就越高。具体的分数和等级如下表所示: 2 每级的特点 茶叶的质量等级…

OceanBase SQL 诊断和调优实践——【DBA从入门到实践】第七期

数据库作为绝大多数应用系统储存数据的核心系统,在用户系统需要访问数据时,有着至关重要的作用。在这些交互中,SQL 语言是应用与数据库系统之间“沟通”的桥梁,它负责将应用的指令传达给数据库。因此,SQL 的性能好坏直…

弱类型解析

php中 转化为相同类型后比较 先判断数据类型后比较数值 var_dump("asdf"0);#bool(true) var_dump("asdf"1);#bool(false) var_dump("0asdf"0);#bool(true) var_dump("1asdf"1);#bool(true)1、md5撞库 例&#xff1a; <?php incl…

【智能算法应用】模拟退火算法求解多车型车辆路径问题HFVRP

目录 1.算法原理2.多车型车辆路径HFVRP数学模型3.结果展示4.参考文献5.代码获取 1.算法原理 模拟退火算法&#xff08;Simulated Annealing, SA&#xff09;是一种通用概率算法&#xff0c;用于在给定一个大的搜索空间内寻找问题的近似最优解。这种算法受到物理中退火过程的启…

烟囱ERP系统

一、烟囱系统定义 “烟囱式”系统&#xff0c;来自维基百科的解释是&#xff1a;一种不能与其他系统进行有效协调工作的信息系统&#xff0c;又称为孤岛系统。 二、烟囱系统的案例 比如&#xff1a;就像以下一样&#xff0c;各个系统之间是独立的&#xff0c;所有对接是通过…

深度学习复盘与小实现

文章目录 一、查漏补缺复盘1、python中zip()用法2、Tensor和tensor的区别3、计算图中的迭代取数4、nn.Modlue及nn.Linear 源码理解5、知识杂项思考列表6、KL散度初步理解 二、处理多维特征的输入1、逻辑回归模型流程2、Mini-Batch (N samples) 三、加载数据集1、Python 魔法方法…

c++笔记3

优先队列 普通的队列是一种先进先出的数据结构&#xff0c;元素在队列尾追加&#xff0c;而从队列头删除。优先队列是一种按照优先级决定出队顺序的数据结构&#xff0c;优先队列中的每个元素被赋予级别&#xff0c;队首元素的优先级最高。 例如&#xff1a;4入队&#xff0c…

多文件和静态/动态链接以及虚拟内存管理

多目标文件链接 //stack.c char stack[512]; int top -1; void push(char c){stack[top] c; }char pop(void){return stack[top--]; }int is_empty(void){return top 1; }// main.c #include <stdio.h> int a,b 1; int main(){ push(a); push(b); push(c); while(!is…

应用程序图标提取

文章目录 [toc]提取过程提取案例——提取7-zip应用程序的图标 提取过程 找到需要提取图标的应用程序的.exe文件 复制.exe文件到桌面&#xff0c;并将复制的.exe文件后缀改为.zip 使用解压工具7-zip解压.zip文件 在解压后的文件夹中&#xff0c;在.rsrc/ICON路径下的.ico文件…

代码随想录-Day20

654. 最大二叉树 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。 递归地在最大值 左边 的 子数组前缀上 构建左子树。 递归地在最大值 右边 的 子数组后缀上 构建右子树。 返回 nums…

ROS | 激光雷达包格式

ros激光雷达包格式&#xff1a; C实现获取雷达数据 &#xff1a; C语言获取雷达数据&#xff1a; Python语言获取雷达数据&#xff1a; python不需要编译&#xff0c;但是需要给它一些权限 chmod x lidar_node.py(当前的文件名字&#xff09; C实现雷达避障&#xff1a; python…

【Xilinx】常用的全局时钟资源相关Xilinx器件原语

1 概述 常用的与全局时钟资源相关的Xilinx器件原语包括&#xff1a; IBUFGIBUFGDS、OBUFGDS 和 IBUFDS、OBUFDSBUFGBUFGPBUFGCEBUFGMUXBUFGDLLIBUFDS_GTXE1IBUFDS_GTE2IBUFDS_GTE3OBUFDS_GTE3IBUFDS_GTE4OBUFDS_GTE4DCM 刚开始看到这写源语&#xff0c;免不了好奇这些源语对应的…

IDEA如何对多线程进行debug

开发中使用到多线程的时候不少,但是debug起来还是比较困难的,因为默认每次只会进入一个线程,这样有些问题是发现不了的,其实IDEA也是支持进入每个线程来debug的 写一个简单的demo public class ThreadDebug {public static void main(String[] args) {MyThread myThread new…

异方差的Stata操作(计量114)

以数据集 nerlove.dta 为例&#xff0c;演示如何在 Stata 中处理异方差。 此数据集包括以下变量&#xff1a; tc ( 总成本 ) &#xff1b; q ( 总产量 ) &#xff1b; pl ( 工资率 ) &#xff1b; pk ( 资本的使用成本 ) &#xff1b; pf ( 燃料价格 ) &#xff1b; …

GESP等级大纲

CCF编程能力等级认证概述 CCF编程能力等级认证&#xff08;GESP&#xff09;为青少年计算机和编程学习者提供学业能力验证的规则和平台。GESP覆盖中小学阶段&#xff0c;符合年龄条件的青少年均可参加认证。C & Python编程测试划分为一至八级&#xff0c;通过设定不同等级…