被监管警告后,我连夜给系统上了“双保险”!

最近我们部门又被安全监管单位警告了~

原因是公司的核心系统登录校验只有账号密码和数字验证码,安全强度不够。

都2052年了,竟然还有核心系统不做双因子认证的?

没错,就是我们公司。

一定有朋友开始问了,啥是双因子认证?

好的吧,原来大家都一样,那我就放心了~

什么是双因子认证?

勤奋好学的我马上就去问了ChatGPT,得到的回复如下:

双因子认证(2FA,Two-Factor Authentication)是一种增强账户安全性的身份验证方法......

简单来说,双因子认证就是让你用"密码 + 你独有的东西"这两样东西来证明你是你。

把它拆开说就是:

  1. 第一样东西:你知道的

    • 比如你的密码、PIN码、安全问题的答案。这是最常用的,但可能被别人偷走。
  2. 第二样东西:你拥有的 或 你本身的

    • 你拥有的:​ 比如你手机上弹出的验证码 、一个专门的U盾(硬件令牌)、或者绑定了你手机的App。这东西别人很难拿到。
    • 你本身的(生物特征):​ 比如你的指纹面部 或者虹膜。这就是你身体的一部分。

为什么需要双因子认证

像你家大门,如果只用一把锁(密码),小偷撬开锁就能进去。但如果你装了两道锁​(密码 + 指纹),就算小偷知道密码,他没你的指纹也进不去,安全级别大大提升。

所以,双因子认证就是为了给你的账户再加一把别人极难复制的"锁"​

双因子认证的实现方案

1. 方案一:短信/邮箱验证

最常见的实现方案是在密码验证的基础上增加一层短信验证码验证,这也是国内绝大多数互联网信息系统采用最多的一种方案。

用户在系统中绑定一个手机号,每次登录向后台发起获取短信验证码的请求,收到手机短信后输入短信中包含的验证码,后台通过校验用户输入的验证码与生成短信内容时存储的验证码是否一致来确认用户的身份。

流程足够简单,并且在人手一台智能手机的今天,对用户来说足够友好。

邮箱验证码认证与手机短信验证码认证的原理基本一致,这里就不重复介绍了。

那么这是不是最完美的双因子认证实现方案呢?

当然不是,这两种方案虽然足够方便,但安全性实在有限,存在手机sim卡交换攻击、邮箱被盗的风险。

2. 方案二:TOTP验证

说了那么多,有更好的方案吗?

包有的!它是近两年才兴起的方案,也是我个人认为最均衡全面的双因子认证方案。

基于时间的一次性密码 --------- TOTP(Time-based One-Time Password)

其核心思想是客户端和服务器基于同一个密钥和同一个时间,通过同一个算法计算出一个一次性的、短时间有效的数字密码。

举个例子吧,全世界最知名的同性交友网站Github的双因子认证方案使用的就是TOTP。

使用手机认证器App生成一个具有倒计时六位数字设备码,用户在登录系统输入这六位数字设备码,两者一致则认证通过。

那么这串数字设备码是怎么得到的?又为什么更安全?

这就得从TOTP的工作原理开始说起了。

实现步骤

TOTP的实现流程大致可以划分为4个步骤:

1. 生成共享密钥

这是TOTP的第一步,首先服务器生成一个随机密钥(通常是一个 16-32 字节的随机字节数组)。

紧接着将密钥进行 ​Base32​ 编码生成一个字符串(方便显示和扫码),然后通过二维码等方式安全地分享给用户的认证器App。

当用户使用手机认证器App首次进行扫码绑定后,认证器App就会将这个密钥持久化存储在用户的手机设备上,

此后,服务器和用户手机设备上的App都保存着这个相同的密钥,除非重新扫码绑定,否则密钥不会再变更,​这是整个体系的信任根基。

2. 计算时间计数器

前面提到密钥生成后不会再变更,如果通过这个不变的共享密钥直接进行编码生成六位数字设备码,那么这个设备码也是固定不变的,一旦泄漏就失去了安全性。

怎么办?

我们可以增加一个会定期自动更新的变量。

变量需要满足以下特性:

  • 定期自动更新
  • 用户手机设备App上与服务器上需要保持一致

我们很自然就会想到使用系统时间来作为变量。

服务器和认证器APP同时获取当前时间的时间戳(T),并除以时间步长(一般为30),就能得到一个不断增长的数字,这个数字就是我们的计数器(C)。

C = Math.floor(T / 30)

例如当前北京时间2025-09-14 15:47:24的时间戳为1757836044(s),时间步长为30,那么

Math.floor(1757836044 / 30) = 58594534

58594534这个数字表示从1970-01-01 00:00:00到2025-09-14 15:47:24一共经过了58594534个30秒。

为什么我们不直接使用时间戳作为变量而是计数器?

如果直接使用时间戳作为变量,服务器和认证器APP两个不同的端容易产生时间误差导致验证失败。

而如果使用由时间戳/时间步长得到的数字则不会有这个问题,同时也不影响到整体的安全性。

3. 获取数字设备码

上面我们介绍了TOTP的两个核心原料,共享密钥和计数器,那么如何将两个原料变成认证器App上的六位数字设备码?

  1. 使用共享密钥(Base32解码)和计数器的字节数组作为输入,通过HMAC-SHA-1算法计算出一个消息认证码(哈希值)
  2. 算法通过哈希值的最后一个字节的低4位确定起始偏移量,然后取4个字节组成一个整数
  3. 将得到的整数对 10^6 (1,000,000) 取模,并格式化为6位字符串,不足位用前导零补齐.

这样就得到一个六位数字设备码。

4. 登录验证

用户登录时输入帐号密码以及手机认证器App上的六位数字设备码,向服务端发起登录请求。

接着服务端从数据库中取出与该帐号关联的共享密钥,通过算法得到六位数字设备码。

最后将服务端生成的六位数字设备码与登录时用户输入的六位数字设备码对比是否一致,一致则验证通过,完成登录。

流程梳理

我们来梳理一下TOTP的整个实现流程。

  1. 用户在采用TOTP双因子登录认证的网站上使用手机认证器App扫码绑定,生成共享密钥。

扫码时对共享密钥进行Base32编码并返回给认证器App进行客户端持久化存储,同时在数据库也存储了一份(键为帐号名,值为编码后的共享密钥)。

  1. 绑定完成后,认证器App展示动态更新的六位数字设备码以及更新倒计时。

绑定操作之后认证器App不再与服务端进行交互,设备码的更新以及倒计时都是在App端独立完成。

设备码的生成与服务端使用相同的算法,倒计时则通过C = Math.floor(T % 30)计算得到,因此认证器App即使离线也能正常使用。

  1. 用户需要登录网站时,输入帐号密码以及认证器App上的六位数字设备码,向服务端发起登录请求,服务端进行校验。

在校验设备码的有效性时,服务端使用计数器(C、C-1、C+1)与共享密钥生成三个六位数字设备码,使用三个相邻的计数器生成的三个设备码任意一个与客户端一致则认为有效。

这样既能避免客户端与服务端时间存在轻微错位导致校验失败,也不影响整体的安全性。

3. 其它方案

除了上面给大家介绍的这两种常用的双因子认证方案外,还存在其它几种较主流的方案,下面给大家做个简单的介绍,感兴趣的朋友可以自行了解,这里就不展开篇幅了。

  • 物理安全密钥(U2F/FIDO2)​​:

    • 原理:使用物理硬件设备(如YubiKey)进行认证,通常采用公钥加密技术,安全性极高,能有效防范钓鱼攻击。
    • 体验:插入设备或 NFC 触碰即可完成验证。
  • 推送通知​:服务器发送一个认证请求到你的App(如手机微信、Authy),用户手动确认通过。

  • 生物识别​:如手机的Face ID、Touch ID,通常作为本地验证手段。

结语

说白了,双因子认证就是你账户的"双保险"。光有密码真的不够用。

现在黑产那么发达,撞库、钓鱼防不胜防,加个双因子,就算你密码不小心泄露了,别人没你手机或U盾也进不去。

方案没有最好,只有最合适

  • 📱 短信验证码:最方便,用户都会用。但得注意手机别丢,小心SIM卡被复制(虽然概率低)。
  • 🔢 TOTP(手机认证器App)​:安全性更高,不用联网也能用。适合对安全要求高的系统,用户扫个码绑定一下就行。
  • 🔑 物理密钥/U盾:最安全,但成本高、体验重。一般银行、政府用的多。
  • 👆 指纹/人脸:体验最无感,但需要硬件支持。适合移动端。

咱们这核心系统,既然都被监管点名了,肯定得尽快升级,最终我们选用了第一种方案,理由是够方便,开发成本低,用户接受度高。

安全这事儿吧,平时觉得麻烦,真出事了就是大事,还是早做早踏实!

这波整改之后,总算能睡个安稳觉了~

相关推荐
用户962377954481 天前
VulnHub DC-3 靶机渗透测试笔记
安全
叶落阁主2 天前
Tailscale 完全指南:从入门到私有 DERP 部署
运维·安全·远程工作
用户962377954484 天前
DVWA 靶场实验报告 (High Level)
安全
数据智能老司机4 天前
用于进攻性网络安全的智能体 AI——在 n8n 中构建你的第一个 AI 工作流
人工智能·安全·agent
数据智能老司机4 天前
用于进攻性网络安全的智能体 AI——智能体 AI 入门
人工智能·安全·agent
用户962377954484 天前
DVWA 靶场实验报告 (Medium Level)
安全
red1giant_star4 天前
S2-067 漏洞复现:Struts2 S2-067 文件上传路径穿越漏洞
安全
用户962377954484 天前
DVWA Weak Session IDs High 的 Cookie dvwaSession 为什么刷新不出来?
安全
cipher6 天前
ERC-4626 通胀攻击:DeFi 金库的"捐款陷阱"
前端·后端·安全
一次旅行9 天前
网络安全总结
安全·web安全