1.引入maven依赖
<dependency> <groupId>com.amdelamar</groupId> <artifactId>jotp</artifactId> <version>1.3.0</version> </dependency>
2.测试类1.TOTPpackage 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.HOTPpackage 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更适合系统之间的认证