使用jotp实现双因子验证

简介: 扫盲使用totp增强身份安全性指南,原理看懂也不用自己造轮子呀,最讨厌哪些啥也不懂的搬运工,我这里给大家解惑吧

1.totp是什么

TOTP 是Time-based One-Time Password的简写,表示基于时间戳算法的一次性密码。 是时间同步,基于客户端的动态口令和动态口令验证服务器的时间比对,一般每60秒,或30秒产生一个新口令,要求客户端和服务器能够十分精确的保持正确的时钟,客户端和服务端基于时间计算的动态口令才能一致。 

适用场景

  • 服务器登录动态密码验证
  • 公司VPN登录双因素验证
  • 银行转账动态密码
  • 网银、网络游戏的实体动态口令牌
  • 等基于时间有效性验证的应用场景

2. jotp java实现

OTP (One Time Password) utility in Java. To enable two-factor authentication (2FA) using HMAC-based or Time-based algorithms.

官网:https://amdelamar.com/jotp/

  • pom文件引入依赖

    <dependency>
        <groupId>com.amdelamar</groupId>
        <artifactId>jotp</artifactId>
        <version>1.3.0</version>
    </dependency>
    
  • 使用

    import com.amdelamar.jotp.OTP;
    import com.amdelamar.jotp.type.Type;
    
    //基于系统时间产生一个base32加密的随机密钥因子,根据密钥生成对应的验证码,验证码6位
    // Random secret Base32 with 20 bytes (160 bits) length
    // (Use this to setup 2FA for new accounts).
    String secret = OTP.randomBase32(20);
    // Returns: IM4ZL3G5Q66KW4U7PMOQVXQQH3NGOCHQ
    
    // Generate a Time-based OTP from the secret, using Unix-time
    // rounded down to the nearest 30 seconds.
    String hexTime = OTP.timeInHex(System.currentTimeMillis());
    String code = OTP.create(secret, hexTime, 6, Type.TOTP);
    
  • java示例

import org.jotp.TOTP;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

@Controller
public class AuthenticationController {
   

    private static final String SECRET_KEY = "mysecretkey"; // 你需要为每个用户生成一个唯一的密钥

    @GetMapping("/login")
    public String showLoginForm() {
   
        return "login";
    }

    @PostMapping("/login")
    public String authenticate(@RequestParam String username, @RequestParam String password, @RequestParam String totpToken, Model model) {
   
        boolean isAuthenticated = authenticateUser(username, password, totpToken);
        if (isAuthenticated) {
   
            return "redirect:/home";
        } else {
   
            model.addAttribute("error", "Invalid username, password, or TOTP token");
            return "login";
        }
    }

    private boolean authenticateUser(String username, String password, String totpToken) {
   
        // 验证用户名和密码
        // 在这里添加你的代码,从数据库中获取用户的凭据,并验证用户名和密码是否匹配

        // 验证TOTP令牌
        long timeWindow = 30; // TOTP令牌的时间窗口为30秒
        int tokenLength = 6; // TOTP令牌长度为6位数
        int validationWindow = 1; // 验证窗口为1个时间窗口

        long currentTimestamp = System.currentTimeMillis() / 1000L;
        long[] timeValues = {
   currentTimestamp / timeWindow};
        String[] totpValues = {
   totpToken};

        TOTP totp = new TOTP(SECRET_KEY, timeWindow, tokenLength);
        boolean isValid = totp.verify(timeValues, totpValues, validationWindow);

        return isValid;
    }

}

在以上代码中,我们首先定义了一个名为SECRET_KEY的静态常量,用于存储每个用户的TOTP密钥。然后,我们实现了一个名为showLoginForm()的GET请求处理方法,用于显示登录表单。接着,我们实现了一个名为authenticate()的POST请求处理方法,用于验证用户的凭据和TOTP令牌。如果验证成功,则将用户重定向到主页;否则,将显示一个错误消息。

在authenticateUser()方法中,我们首先验证用户名和密码是否匹配。然后,我们使用JOTP库来验证TOTP令牌是否有效。需要注意的是,在实际应用中,你需要为每个用户生成一个唯一的密钥,并将其存储在数据库中。每个TOTP令牌都是基于密钥生成的,并且只有拥有正确密钥的人才能生成有效令牌。因此,你需要确保密钥是安全的,并且不会被泄露。

3.将生成的32位base32密钥保存到手机app

这里我们使用手机应用应用商城的 google authenticator ,不需要登录。

如何安装,请参考https://support.google.com/accounts/answer/1066447?hl=zh-Hans&co=GENIE.Platform%3DAndroid Google 身份验证器

网上大多是那种看了都不知道怎么办的文章,我就当给大家扫盲了,配置好后端和前端,你就可以根据自己的动态令牌去做一些安全验证了,一码在手,天下我有!

相关文章
|
安全 Java 数据库
安全无忧!在 Spring Boot 3.3 中轻松实现 TOTP 双因素认证
【10月更文挑战第8天】在现代应用程序开发中,安全性是一个不可忽视的重要环节。随着技术的发展,双因素认证(2FA)已经成为增强应用安全性的重要手段之一。本文将详细介绍如何在 Spring Boot 3.3 中实现基于时间的一次性密码(TOTP)双因素认证,让你的应用安全无忧。
1350 5
|
机器学习/深度学习 数据可视化 计算机视觉
YOLOv5改进 | 2023Neck篇 | 轻量级跨尺度特征融合模块CCFM(附yaml文件+添加教程)
YOLOv5改进 | 2023Neck篇 | 轻量级跨尺度特征融合模块CCFM(附yaml文件+添加教程)
1426 1
|
12月前
|
SQL 人工智能 数据可视化
16.1k star! 只需要DDL就能一键生成数据库关系图!开源神器ChartDB让你的数据结构"看得见"
ChartDB是一款开源的数据库可视化神器,通过一句智能查询就能自动生成专业的数据库关系图。无需安装客户端、不用暴露数据库密码,打开网页就能完成从数据建模到迁移的全流程操作,堪称开发者的"数据库透视镜"。
2414 67
ly~
|
消息中间件 存储 监控
如何查看 RocketMQ 消息的重试次数和时间间隔?
RocketMQ消息重试次数和时间间隔可通过查看消费者和Broker日志、使用管理控制台的监控页面和消息查询功能,或通过分析消费者代码和RocketMQ客户端库代码等方式获取。日志中常有消费失败重试的明确记录,控制台可监控消费情况推断重试状态,代码分析则适合技术用户深入了解。
ly~
1249 3
|
负载均衡 算法 应用服务中间件
Nginx入门 -- 理解 Nginx 的请求处理流程
Nginx入门 -- 理解 Nginx 的请求处理流程
916 1
|
Java API Maven
bcprov-jdk15on是什么依赖用在哪里
【6月更文挑战第11天】bcprov-jdk15on是什么依赖用在哪里
8288 3
|
安全 数据安全/隐私保护
【GitHub】2FA认证(双重身份验证)
【GitHub】2FA认证(双重身份验证)
7597 6
|
安全 Java 数据安全/隐私保护
Spring Boot中的数据加密与解密
Spring Boot中的数据加密与解密
|
存储 数据采集 监控
Flume 拦截器概念及自定义拦截器的运用
Apache Flume 的拦截器是事件处理组件,位于Source和Channel之间,用于在写入Channel前对数据进行转换、提取或删除。它们支持数据处理和转换、数据增强、数据过滤以及监控和日志功能。要创建自定义拦截器,需实现Interceptor接口,包含initialize、intercept、intercept(List&lt;Event&gt;)和close方法。配置拦截器时,通过Builder模式实现Interceptor.Builder接口。在Flume配置文件中指定拦截器全类名,如`TestInterceptor$Builder`,然后启动Flume进行测试。
776 0
|
机器学习/深度学习 编解码 数据可视化
全新ViT Backbone | 混合卷积与Attention设计的SMT更快、更小也更强
全新ViT Backbone | 混合卷积与Attention设计的SMT更快、更小也更强
607 1