OTP:Java一次动态密码、付款码原理

1. 什么是OTP

    一次性密码(One Time Password,简称OTP),又称“一次性口令”,是指只能使用一次的密码。

2. OTP原理

动态密码的产生方式,主要是以时间差做为服务器与密码产生器的同步条件。在需要登录的时候,就利用密码产生器产生动态密码,OTP一般分为计次使用以及计时使用两种,计次使用的OTP产出后,可在不限时间内使用;计时使用的OTP则可设置密码有效时间,从30秒到两分钟不等,而OTP在进行认证之后即废弃不用,下次认证必须使用新的密码,增加了试图不经授权访问有限制资源的难度。
计算公式:
OTP(K,C) = Truncate(HMAC-SHA-1(K,C))工作原理

3.Java实现全代码TOTP

该代码可以直接运行

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.lang.reflect.UndeclaredThrowableException;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.util.Date;


public class TOTP {
   

    public static void main(String[] args) {
   
        try {
   

            for (int j = 0; j < 10; j++) {
   
                String totp = generateMyTOTP("account01", "12345");
                System.out.println(String.format("加密后: %s", totp));
                Thread.sleep(1000);
            }

        } catch (final Exception e) {
   
            e.printStackTrace();
        }
    }

    /**
     * 共享密钥
     */
    private static final String SECRET_KEY = "ga35sdia43dhqj6k3f0la";

    /**
     * 时间步长 单位:毫秒 作为口令变化的时间周期
     */
    private static final long STEP = 5000;

    /**
     * 转码位数 [1-8]
     */
    private static final int CODE_DIGITS = 8;

    /**
     * 初始化时间
     */
    private static final long INITIAL_TIME = 0;
  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是用 Java 生成动态令牌 OTP 的示例代: ```java import java.util.Date; import java.util.Random; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base32; public class OTPUtil { private static final int DIGITS = 6; private static final int PERIOD = 30; public static String generateOTP(String secretKey) { try { byte[] keyBytes = new Base32().decode(secretKey); // 获取当前时间戳,单位为秒 long timestamp = new Date().getTime() / 1000; // 计算时间戳的时间段 long counter = timestamp / PERIOD; // 将计数器转为字节数组 byte[] counterBytes = new byte[8]; for (int i = counterBytes.length - 1; i >= 0; i--) { counterBytes[i] = (byte) (counter & 0xff); counter >>= 8; } // 计算 HMAC-SHA1 哈希值 Mac mac = Mac.getInstance("HmacSHA1"); mac.init(new SecretKeySpec(keyBytes, "RAW")); byte[] hash = mac.doFinal(counterBytes); // 获取哈希值的低位 4 位字节 int offset = hash[hash.length - 1] & 0xf; int binary = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16) | ((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff); // 对低位 4 位字节进行模运算 int otp = binary % (int) Math.pow(10, DIGITS); // 将 OTP 转为字符串 String otpStr = Integer.toString(otp); while (otpStr.length() < DIGITS) { otpStr = "0" + otpStr; } return otpStr; } catch (Exception e) { throw new RuntimeException(e); } } public static String generateSecretKey() { byte[] bytes = new byte[20]; new Random().nextBytes(bytes); return new Base32().encodeAsString(bytes); } } ``` 这段代使用了 Google Authenticator 的算法,可以生成 6 位数字的动态令牌 OTP。其中 `generateSecretKey` 方法用于生成随机的密钥,可以将生成的密钥通过二维等方式传递给用户,让用户将其添加到 Authenticator 应用中。`generateOTP` 方法用于根据密钥生成动态令牌 OTP,可以在用户登录、重置密码等需要验证身份的场景中使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值