• java 双因素认证(2FA)TOTP demo


    TOTP 的全称是"基于时间的一次性密码"(Time-based One-time Password)。它是公认的可靠解决方案,已经写入国际标准 RFC6238。
    很早就知道有这个东西了,一直不知道是怎么实现的.
    比如 QQ 安全中心的密钥,U盾,就是动态密码之类的.
    今天看到阮一峰老师的博客才知道实现原理.
    概念性的东西参考
    http://www.ruanyifeng.com/blog/2017/11/2fa-tutorial.html
    实现代码:

    package totp;
    
    import java.security.MessageDigest;
    import java.util.Date;
    import java.util.UUID;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class TOTP {
    
    	// TC = floor((unixtime(now) − unixtime(T0)) / TS)
    	// TC = floor(unixtime(now) / 30)
    	// TOTP = HASH(SecretKey, TC)
    	private static final char[] HEX_DIGITS = "0123456789abcdef".toCharArray();
    
    	public static void main(String[] args) {
    
    		Pattern pattern = Pattern.compile("\\d");
    		String key = UUID.randomUUID().toString().replace("-", "");
    
    		for (int i = 0; i < 70; i++) {
    
    			String TC = String.valueOf((int) Math.floor(new Date().getTime() / 1000 / 30));
    			String TOTP = sha1(TC + key);
    
    			Matcher matcher = pattern.matcher(TOTP);
    			String result = "";
    			while (matcher.find()) {
    				result += matcher.group();
    			}
    			result = result.substring(result.length() - 6);
    			System.out.println(i + "  --  " + result);
    
    			try {
    				Thread.sleep(1000);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    	}
    
    	public static String sha1(String srcStr) {
    		return hash("SHA-1", srcStr);
    	}
    
    	public static String hash(String algorithm, String srcStr) {
    		try {
    			MessageDigest md = MessageDigest.getInstance(algorithm);
    			byte[] bytes = md.digest(srcStr.getBytes("utf-8"));
    			return toHex(bytes);
    		} catch (Exception e) {
    			throw new RuntimeException(e);
    		}
    	}
    
    	public static String toHex(byte[] bytes) {
    		StringBuilder ret = new StringBuilder(bytes.length * 2);
    		for (int i = 0; i < bytes.length; i++) {
    			ret.append(HEX_DIGITS[(bytes[i] >> 4) & 0x0f]);
    			ret.append(HEX_DIGITS[bytes[i] & 0x0f]);
    		}
    		return ret.toString();
    	}
    }
    
    
    有问题请联系hudcan@sina.com 个人网站:http://ext.123456cc.cc
  • 相关阅读:
    N个数求和
    求整数段和
    连续因子
    L1-005 考试座位号
    PTA Java tips(转载)
    个位数统计
    flink编译支持CDH6.2.0(hadoop3.0.0)
    hdfs/hbase 程序利用Kerberos认证超过ticket_lifetime期限后异常
    spring boot通过@Bean注解定义一个Controller
    【TypeScript】TypeScript 学习 2——接口
  • 原文地址:https://www.cnblogs.com/mysgk/p/9427246.html
Copyright © 2020-2023  润新知