为 Linux 服务器 SSH 添加 TOTP 动态验证码以及 Java 实现算法
0x00 TOTP 动态验证码?
TOTP 基于时间的一次性密码算法(Time-Based One-Time Password)是一种根据预共享的密钥与当前时间计算一次性密码的算法,利用不同设备时间相同的特性,将时间作为特定算法的一部分从而达到无需网络进行安全验证的目的。 该算法有两个输入,一个输出,一个输入是随机生成的密钥,密钥需要被验证方和验证器同时持有,另一个输入即系统时间,通常是 UNIX 时,输出则是两方相同的验证码。一般的验证码有效期为 30 秒,每 30
秒生成一个新的验证码。当前有很多领域和行业在使用 TOTP 作为它们的安全验证,比如银行使用的实体验证器,网易的网易将军令等。
这套算法在 RFC6238 中有详细的说明,在后面的实现算法部分详细说明。
0x01 Linux 服务器安装 Google Authenticator
服务器采用腾讯云轻量服务器 Debian Linux 系统,腾讯云轻量服务器是腾讯云基于 CVM 服务器推出以应用为中心的轻量级服务器,优点在于快速部署应用、价格便宜等。有需要在云环境练习 Linux 技能的推荐购买 【腾讯云】云产品限时秒杀,爆款2核4G云服务器首年74元 【腾讯云】境外1核2G服务器低至2折,半价续费券限量免费领取!
- SSH 远程登录后 先更新当前源列表
- apt update
- apt install libpam-google-authenticator
- 输入 google-authenticator 并按照说明进行配置
- google-authenticator
图中黄线框部分为密钥,红色线框部分为备用验证码,备用验证码是在丢失验证器的情况下输入的验证码,验证码输入后将失效。请妥善保管这两个内容,它们是生成验证码的关键,也请不要泄露这个二维码
粗略翻译下选项
- Do you want authentication tokens to be time-based
需要启用基于时间的认证吗?
Do you want me to update your "/root/.google_authenticator" file?
需要更新配置文件吗?
Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks ?
禁止多次使用同一个身份验证令牌吗?这将限制大约每 30 秒登录一次,它将减少中间人攻击的机会
By default, a new token is generated every 30 seconds by the mobile app.
In order to compensate for possible time-skew between the client and the server,
we allow an extra token before and after the current time. This allows for a
time skew of up to 30 seconds between authentication server and client. If you
experience problems with poor time synchronization, you can increase the window
from its default size of 3 permitted codes (one previous code, the current
code, the next code) to 17 permitted codes (the 8 previous codes, the current
code, and the 8 next codes). This will permit for a time skew of up to 4 minutes
between client and server.
Do you want to do so?
默认情况下,移动应用程序每 30 秒生成一个新令牌。
为了补偿客户端和服务器之间可能的时间偏差,
我们允许在当前时间之前和之后一个额外的令牌。这允许一个
身份验证服务器和客户端之间的时间偏差最大为 30 秒。如果你
遇到时间同步不好的问题,可以增加窗口
从其默认大小的 3 个允许代码(一个以前的代码,当前的
代码,下一个代码)到 17 个允许的代码(前 8 个代码,当前代码
代码,以及接下来的 8 个代码)。这将允许最多 4 分钟的时间偏差
客户端和服务器之间。
要这样做吗?
If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting?
如果您登录的计算机没有针对蛮力进行强化
登录尝试,您可以为身份验证模块启用速率限制。
默认情况下,这会将攻击者限制为每 30 秒不超过 3 次登录尝试。
您要启用速率限制吗?
- 这个时候二步认证是还没有生效的,还需要修改 pam 以及 ssh 配置,请仔细小心地修改配置,任何一处错误都可能导致 ssh 无法连接
鉴于操作危险性,建议提前对机子进行备份,比如 腾讯云轻量 的镜像备份,一个地区五个免费配额,不用白不用是吧 (手动狗头)
文件 /etc/pam.d/sshd
- 添加一行 auth required pam_google_authenticator.so
文件 /etc/ssh/sshd_config
- ChallengeResponseAuthentication no 更改为 ChallengeResponseAuthentication yes
- 保存好二维码、密钥以及备用验证码后断开连接重新登录服务器,这时输入密码后将会出现二步验证
目前有很多家验证器客户端 比较流行的有 Google Authenticator 、 Microsoft Authenticator、Authy 等。
Microsoft Authenticator、Authy 相比 Google Authenticator 多了一套云同步系统,能防止意外清除软件数据之后丢失密钥导致的各种问题出现。但请注意,选择了带有云同步功能的应用中使用的同步账号必须设置一个高强度密码,避免同步账号被盗取泄露验证码。
因为各家 Authenticator 都不允许界面截图,所以它欠咱几张图片
这里选用 Google Authenticator 下载安装后进入软件,选择扫描条形码,然后扫描上面保存的图片即可,或选择手动输入,账户为备注名字,可随意,密钥则为保存的密钥。
0x03 算法原理
现有实现了 TOTP 的软件中的算法 本质上就是 HMAC-SHA-1 算法,也就是带有盐值的 SHA-1
- 以 secret 密钥为盐值取当前时间的摘要,即 HMAC-SHA-1(K,C)
K 为密钥,C 为当前 UNIX 时间 / 30,之所以除以 30 就是为了取整获得一个 30 内相同的值
这样就得到了一个原始的哈希值,当然得到这个哈希值还不行,因为哈希值是 20 字节长的,对于 30 秒的验证码来说太长了,所以 HEX = HMAC-SHA-1(K,C)等下还要用取 HEX 的第 20 字节,也就是 HEX[19] 的低四位(后四位)作为偏移量 OFFEST在 HEX 中,从偏移量 OFFEST 开始取四个字节作为验证码中间值 WIP将 WIP mod 10^6 得到 6 位数字,不够 6 位高位补 0 即验证码
举个例子
0x04 使用 Java 实现算法
呜呜呜是不是我太菜了,代码贴上来字数就超了 要不要不,看我发在其它地方的版本吧 qwq 知乎
0x05 最后
文章中可能还有错误的地方,欢迎各位提出。
文中提及的代码均在我的开源 Java 中间件项目 Cynops 中 ,欢迎 Star ,也可以 Follow 我的 Github Hanbings 还请前辈们多多指教。
热议
2楼 zzzzzsa 6天前
顶 项目很有意思
3楼 ukx 6天前
Make
4楼 咸鱼咸鱼 6天前
一眼腾讯云软文
5楼 htazq 6天前
Mark一下,技术贴帮顶
6楼 darius 6天前
技术贴必顶
7楼 TvT 6天前
8楼 寒冰hanbings 6天前
一眼腾讯云软文
阿巴阿巴阿巴 也不是很软吧 要不是代码发不上来
9楼 moehentai2333 6天前
你出寒冰?鹅鹅出火拳!
10楼 Marlene 6天前
很有意思 但对sshd不是很熟悉 生产环境怕一不小心就改坏了
如果有稳定的shell一键脚本就更好了
12楼 Eric.c 6天前
sftp可用?
13楼 konololi 6天前
增加密码泄漏风险
14楼 875 6天前
想问下 这个动态跟密钥相比哪个更好?
15楼 rem 6天前
花里胡哨
16楼 HOH 6天前
自找麻烦,还不如自己写一个挑战码登录简单
17楼 Meocat 6天前
这下可安全了
18楼 在線 6天前
现在新注册的都这么厉害吗 比90%MJJ强
19楼 腿毛飘飘 6天前
脱裤子放屁,是证书登录不香了还是证书登录不香了?
20楼 寒冰hanbings 6天前
想问下 这个动态跟密钥相比哪个更好?
密钥安全 如果没有密码要求上密钥 密钥也可以再加这个动态码 不过相比密钥的安全性没什么必要就是了
22楼 寒冰hanbings 6天前
脱裤子放屁,是证书登录不香了还是证书登录不香了?
哈哈哈 密钥登录更安全 上了密钥登录也不是很必要加动态验证码了 不过给密码登录多一个保护嘛 需求还是有的
23楼 875 6天前
密钥安全 如果没有密码要求上密钥 密钥也可以再加这个动态码 不过相比密钥的安全性没什么必要就是了 ...
哈哈 那还不错刚研究两天瞎写整合了个密钥脚本,你这出了个动态验证,吓得我以为白忙活了
24楼 笑花落半世琉璃 6天前
这v佬还是谁的文章我记得里面的两步验证内容内容我现在还记得大概
记得以前操作直接吧自己也给锁外面
25楼 寒冰hanbings 6天前
笑花落半世琉璃 发表于 2021-12-21 23:06
这v佬还是谁的文章我记得 里面的两步验证内容内容我现在还记得大概记得以前操作直接吧自己也给 ...
嘿嘿 原创的哦 是我自己的
26楼 fmbfmb 5天前
mark
27楼 Romeoiii 5天前
这教程我早就在其它地方看过,是另一个作者发布的,当时看了,觉得还可以,多了一层保护,vps上有特别重要的东西,就可以用这个,防患于未然
28楼 biubiu 5天前
有没有给win上这个的方法,感觉也听有必要
29楼 amao000765 5天前
这么说吧 绝大多数机器被黑,并不是应为密码太弱被爆破,而是因为各种程序漏洞导致机器失陷。
30楼 寒冰hanbings 3天前
amao000765 发表于 2021-12-22 08:26
这么说吧 绝大多数机器被黑,并不是应为密码太弱被爆破,而是因为各种程序漏洞导致机器失陷。 ...
是这么回事 但防患于未然嘛 多一个防护也没什么不好的
32楼 philsilver 昨天02:10
战略mark,回头有时间弄一下
33楼 SmallL_U 昨天22:33
寒冰 是不是你(Doge 难道遇到熟人了
34楼 寒冰hanbings 昨天23:03
寒冰 是不是你(Doge 难道遇到熟人了
是我
35楼 Function 昨天23:12
36楼 caizi 18分钟前
好几年前就上两步验证了,增加了一层,反正想暴力破解ssh是不可能了。
腾讯云的软广?两步验证是随便一台机器都能上的,不是非要这破腾讯云的才行的。
申明:本文内容由网友收集分享,仅供学习参考使用。如文中内容侵犯到您的利益,请在文章下方留言,本站会第一时间进行处理。