当前位置: 首页 > 图灵资讯 > 技术篇> 使用二次验证码OTP

使用二次验证码OTP

来源:图灵教育
时间:2023-06-07 09:34:51

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.longg在timeInHex方法中 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更适合系统之间的认证