0
点赞
收藏
分享

微信扫一扫

使用二次验证码OTP

1.引入maven依赖

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

2.测试类

1.TOTP

package org.example.otp;

import com.amdelamar.jotp.OTP;
import com.amdelamar.jotp.type.Type;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * @author gltqe
 * @date 2023/6/6 15:33
 */
public class OtpTest {
    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, IOException, InterruptedException {
        // 生成随机秘钥 (secret可以根据用户名从库里查出来)
        String secret = OTP.randomBase32(20);
        System.out.println("Secret: " + secret);
        // 使用当前的时间戳作为种子来生成随机数
        long l1 = System.currentTimeMillis();
        System.out.println("l1 :" + l1);
        // 转为16进制
        String hexTime1 = OTP.timeInHex(l1,35);
        System.out.println("hexTime1: " + hexTime1);
        // 创建验证码
        String code = OTP.create(secret, hexTime1, 6, Type.TOTP);
        System.out.println("code: " + code);

        // 模拟 一定时间后 输入的code
//        String inCode = "123456";
        String inCode = code;
        Thread.sleep(26000);

        // 获取输入时的时间戳
        long l2 = System.currentTimeMillis();
        System.out.println("l2 :" + l2);
        // 转为16进制
        // timeInHex方法中使用 输入时的时间戳 除以 周期 得到商相同 则证明 没有超过周期 所以hexTime2 和 hexTime1 相等
        String hexTime2 = OTP.timeInHex(l2,35);
        System.out.println("hexTime2: " + hexTime2);
        // 验证
        boolean verify = OTP.verify(secret, hexTime2, inCode, 6, Type.TOTP);
        System.out.println(verify);

    }
}

2.HOTP

package org.example.otp;

import com.amdelamar.jotp.OTP;
import com.amdelamar.jotp.type.Type;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * @author gltqe
 * @date 2023/6/6 15:33
 */
public class OtpTest2 {
    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, IOException, InterruptedException {
        // 生成随机秘钥 (secret可以根据用户名从库里查出来)
        String secret = OTP.randomBase32(20);
        System.out.println("Secret: " + secret);
        // hotp要输入数字 
        String num1 = "1000";
        // 创建验证码
        String code = OTP.create(secret, num1, 6, Type.HOTP);
        System.out.println("code: " + code);

        // 模拟 一定时间后 输入的code 和 数字
//        String inCode = "123456";
        String inCode = code;
        Thread.sleep(6000);
        String num2 = "1001";
        // 验证 输入num1 验证通过 num2 验证失败
        boolean verify = OTP.verify(secret, num1, inCode, 6, Type.HOTP);
        System.out.println(verify);
    }
}

3.注意事项

// 在OTP.timeInHex方法中
long time = (long)Math.floor((double)Math.round((double)timeInMillis / 1000.0) / period);
/**

两次时间戳如果不超过周期(period)所得商(time)是一样的,所以最后得到的16进制是一样的

但是使用的Math.round是四舍五入 Math.floor是向下取整,所以会存在一定误差
比如: 生成时时间戳为 1686041720632 验证时时间戳为 1686041752272 周期为 35秒
得到的time分别为:48172620 48172621


**/

4.备注

  • TOTP更加适合在用户与系统之间的交互中进行认证
  • HOTP更加适合在系统之间进行认证


举报

相关推荐

0 条评论