|
为 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 远程登录后 先更新当前源列表
[ol]apt update[/ol]复制代码
然后执行安装指令
[ol]apt install libpam-google-authenticator[/ol]复制代码
输入 google-authenticator 并按照说明进行配置
[ol]google-authenticator[/ol]复制代码
图中黄线框部分为密钥,红色线框部分为备用验证码,备用验证码是在丢失验证器的情况下输入的验证码,验证码输入后将失效。请妥善保管这两个内容,它们是生成验证码的关键,也请不要泄露这个二维码
粗略翻译下选项
[ol]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 authenticationtoken? This restricts you to one login about every 30s, but it increasesyour 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 atime skew of up to 30 seconds between authentication server and client. If youexperience problems with poor time synchronization, you can increase the windowfrom its default size of 3 permitted codes (one previous code, the currentcode, the next code) to 17 permitted codes (the 8 previous codes, the currentcode, and the 8 next codes). This will permit for a time skew of up to 4 minutesbetween 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-forcelogin 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 次登录尝试。您要启用速率限制吗?[/ol]复制代码
这个时候二步认证是还没有生效的,还需要修改 pam 以及 ssh 配置,请仔细小心地修改配置,任何一处错误都可能导致 ssh 无法连接
文件 /etc/pam.d/sshd
[ol]添加一行 auth required pam_google_authenticator.so[/ol]复制代码
文件 /etc/ssh/sshd_config
[ol]ChallengeResponseAuthentication no 更改为 ChallengeResponseAuthentication yes[/ol]复制代码
保存好二维码、密钥以及备用验证码后断开连接重新登录服务器,这时输入密码后将会出现二步验证
0x02 设置验证码生成设备
目前有很多家验证器客户端 比较流行的有 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 还请前辈们多多指教。
|
|