复制粘贴即可使用,如有需要,即可修改两个地方:

  1. main里的seed;
  2. poststring;

改以上两处,即可基于时间生成30秒一变的10位数码。

import java.io.UnsupportedEncodingException;
import java.lang.reflect.UndeclaredThrowableException;
import java.security.GeneralSecurityException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
// import java.nio.ByteBuffer;
// import java.util.*;
import java.math.BigInteger;
// import java.util.TimeZone;
import java.util.Base64;public class DTTEST {private DTTEST(){System.out.println("Start:");}/*** This method uses the JCE to provide the crypto algorithm.* HMAC computes a Hashed Message Authentication Code with the* crypto hash algorithm as a parameter.** @param crypto: the crypto algorithm (HmacSHA1, HmacSHA256,*                             HmacSHA512)* @param keyBytes: the bytes to use for the HMAC key* @param text: the message or text to be authenticated = time*/private static byte[] hmac_sha(String crypto, byte[] key, byte[] text){try {// byte[] keyBytes = Base64.getDecoder().decode(key);// byte[] keyBytes = Base64.getDecoder().decode(key);Mac hmac;hmac = Mac.getInstance(crypto);SecretKeySpec macKey =new SecretKeySpec(key, crypto);hmac.init(macKey);return hmac.doFinal(text);} catch (GeneralSecurityException gse) {throw new UndeclaredThrowableException(gse);}}/*** This method converts a HEX string to Byte[]** @param hex: the HEX string** @return: a byte array*/private static byte[] hexStr2Bytes(String hex){// Adding one byte to get the right conversion// Values starting with "0" can be convertedbyte[] bArray = new BigInteger("10" + hex,16).toByteArray();// Copy all the REAL bytes, not the "first"byte[] ret = new byte[bArray.length - 1];for (int i = 0; i < ret.length; i++)ret[i] = bArray[i+1];return ret;}private static final long [] DIGITS_POWER = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000L };// 0  1   2   3       4     5        6         7        8          9          10/*** This method generates a TOTP value for the given* set of parameters.** @param key: the shared secret, HEX encoded* @param time: a value that reflects a time* @param returnDigits: number of digits to return** @return: a numeric String in base 10 that includes*              {@link truncationDigits} digits*/public static String generateTOTP(String key, String time, String returnDigits){return generateTOTP(key, time, returnDigits, "HmacSHA1");}/*** This method generates a TOTP value for the given* set of parameters.** @param key: the shared secret, HEX encoded* @param time: a value that reflects a time* @param returnDigits: number of digits to return** @return: a numeric String in base 10 that includes*              {@link truncationDigits} digits*/public static String generateTOTP256(String key,String time,String returnDigits){return generateTOTP(key, time, returnDigits, "HmacSHA256");}/*** This method generates a TOTP value for the given* set of parameters.** @param key: the shared secret, HEX encoded* @param time: a value that reflects a time* @param returnDigits: number of digits to return** @return: a numeric String in base 10 that includes*              {@link truncationDigits} digits*/public static String generateTOTP512(String key,String time,String returnDigits){return generateTOTP(key, time, returnDigits, "HmacSHA512");}/**
* This method generates a TOTP value for the given
* set of parameters.
*
* @param key: the shared secret, HEX encoded
* @param time: a value that reflects a time
* @param returnDigits: number of digits to return
* @param crypto: the crypto function to use
*
* @return: a numeric String in base 10 that includes
*              {@link truncationDigits} digits
*/public static String generateTOTP(String key,String time,String returnDigits,String crypto){int codeDigits = Integer.decode(returnDigits).intValue();String result = null;// Using the counter// First 8 bytes are for the movingFactor// Compliant with base RFC 4226 (HOTP)while (time.length() < 16 )time = "0" + time;// Get the HEX in a Byte[]
//   byte[] msg = ByteBuffer.allocate(8).putLong(time).array();byte[] msg = hexStr2Bytes(time);byte[] k = hexStr2Bytes(key);byte[] hash = hmac_sha(crypto, k, msg);// put selected bytes into result intint 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);long otp = binary % DIGITS_POWER[codeDigits];result = Long.toString(otp);while (result.length() < codeDigits) {result = "0" + result;}return result;}public static String stringToBase64(String str) {try{String reusult = Base64.getEncoder().encodeToString(str.getBytes("utf-8"));return reusult;}catch (UnsupportedEncodingException e){String msg = "error";return msg;}}public static String stringToHexAscii(String value)  {  StringBuffer sbu = new StringBuffer();  char[] chars = value.toCharArray();   for (int i = 0; i < chars.length; i++) {  sbu.append(Integer.toHexString(Integer.valueOf(chars[i]).intValue()));  }  return sbu.toString();  }  public static String asciiToString(String value) {StringBuffer sbu = new StringBuffer();  char[] chars = value.toCharArray();   for (int i = 0; i < chars.length; i++) {  try{sbu.append( (char) Integer.parseInt(String.valueOf(chars[i])));}  catch(NumberFormatException ex){}}  return sbu.toString();  }/*整体思路:总结:TOTP算法对userid和passwd加密,然后post到指定host;1.原始字符串转换成ASCII码的数字表示;2.ASCII码的数字转换为16进制;3.取原子时的时钟戳,去掉时区。在转换时,考虑int和long int转换的小数舍弃情况;4.设置30S动态时间口令;5.HmacSHA512加密;6.返回结果标准化处理(userid:passwd-timebasedResult);7.对标准化结果进行base64编码;8.Postman的headers增加内容——Authorization: Basic base64编码标准结果;9.Content-Type: application/json;10.Body->raw->content:{"contact_email": "","github_url": ""}*/public static void main(String[] args) {while(true){long T0 = 0;int X = 30;// String steps = "0";String seed = "q506169874@gmail.com";String postString = "HENNGECHALLENGE003";// 通常编码,要将字符串转换编码,然后换成16进制编码;// 一般编程里面,没有特殊要求,编码都是十六进制的String asciiResult = stringToHexAscii(seed + postString);// String asciiResult = "3530363136393837344071712e636f6d48454e4e47454348414c4c454e4745303033";// String asciiResult = stringToBase64(seed + postString);String stringResult = asciiToString(asciiResult);DateFormat df = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");// df.setTimeZone(TimeZone.getTimeZone("JST"));// 此处除以1000,是因为float和int转换会丢弃小数位// 多数编程语言都有一个缺点,两个整数相除。如果结果是小数,最后得出的结果就是一个整数。// 小数位会被丢弃,所以利用这一点,除以30之前,根本不需要做整除的处理。// 浮点的长度普遍比整型长。// 这个计算结果这样,其实是c语言导致的,有浮点数参与计算,结果才可以为浮点。// 数值计算你可以记一个经典例子。1/2=0,1/2.0=0.5,1.0/2=0.5int testTime = (int) (System.currentTimeMillis()/1000L);int reminderTime =X - (int) (System.currentTimeMillis() / 1000 % X);long T = (testTime - T0) / X ;String steps = Long.toHexString(T).toUpperCase();System.out.println("除以30后的时间:"+T);while (steps.length() < 16) steps = "0" + steps;System.out.println(df.format(new Date(System.currentTimeMillis())));System.out.println("unix time(正确):"+testTime);System.out.println("unix time2(原始时间):"+(System.currentTimeMillis()));System.out.println("unix time2(Int转型截取数据):"+(int) (System.currentTimeMillis()));System.out.println("Ascii Result:" + asciiResult);System.out.println("stringResult:" + stringResult);System.out.println("HmacSHA512:"+generateTOTP(asciiResult, steps, "10", "HmacSHA512"));String str = seed + ":" +generateTOTP(asciiResult, steps, "10", "HmacSHA512");System.out.println("str:" + str);String result = stringToBase64(str);System.out.println("result:" + "Basic " + result);while(reminderTime > 0){try {System.out.print(reminderTime+",");Thread.sleep(1000);reminderTime--;}catch (Exception ex){System.out.println("catch a error");}}}
}}

JAVA-基于RFC6238的TOTP算法的简单实现相关推荐

  1. java实现约瑟夫环完整算法_Java简单实现约瑟夫环算法示例

    Java简单实现约瑟夫环算法示例 发布时间:2020-10-01 14:19:56 来源:脚本之家 阅读:104 作者:perfect亮 本文实例讲述了Java简单实现约瑟夫环算法.分享给大家供大家参 ...

  2. java基于Map实现DFA算法

    package com.yangkaile.generator;import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; ...

  3. Java基于优先队列的贪心算法,java

    关于这篇博客 这篇博客是在我读<你不知道的JavaScript-上卷>的时候,遇到的我觉得需要记录下来的知识. 刚好又能够配合之前我写的这篇执行上下文与执行上下文栈博客中关于变量提升与函数 ...

  4. 【Android】基于A星寻路算法的简单迷宫应用

    简介 基于[漫画算法-小灰的算法之旅]上的A星寻路算法,开发的一个Demo.目前实现后退.重新载入.路径提示.地图刷新等功能.没有做太多的性能优化,算是深化对A星寻路算法的理解. 界面预览: 初始化: ...

  5. Java基于socket编程实现局域网内简单通信

    运行客户端程序将创建一个客户端套接字,并与指定的服务器建立连接,接收了服务端发来的消息后关闭连接.服务端启动后会循环接收客户端连接,在接收到连接后,向该客户端发送 "Hello World! ...

  6. java利用TOTP算法动态生成一次性密码

    一.HOTP   HOTP 算法,全称是"An HMAC-Based One-Time Password Algorithm",是一种基于事件计数的一次性密码生成算法,详细的算法介 ...

  7. 关于Google身份验证器、基于时间的一次性密码 (TOTP)算法的初步了解

    一.Google Authenticator 1.概述 Google Authenticator是基于双因素身份验证 ( 2FA ) 的应用程序,有助于识别用户身份并确认用户声称自己是谁以及他是否真的 ...

  8. 基于JPBC的SM9算法的java实现与测试

    文章目录 源码下载 确定参数 R-ate双线性对 定义曲线 辅助方法 密钥结构与算法结果值结构 密钥生成中心KGC SM9算法实现 测试<GMT 0044-2016 SM9标识密码算法:第5部分 ...

  9. 链路状态算法实现Java,JAVA基于蚁群算法路由选择可视化动态模拟(开题报告+任务书+毕业论文+外文翻译+源代码+可执行程序+答辩P...

    JAVA基于蚁群算法路由选择可视化动态模拟(开题报告+任务书+毕业论文+外文翻译+源代码+可执行程序+答辩PPT) 摘 要 路由选择是一种基于网络层的协议,而所有流行的网络层路由选择协议都是基于以下两 ...

最新文章

  1. 数组字段查询不包含_不可不知的可变Java长数组
  2. 非常好!!!Linux源代码阅读——环境准备【转】
  3. UpdatePanel中用后台调用Javascript
  4. 小蚂蚁学习Redis笔记(13)——Redis之phpredis的安装
  5. android 全局对话框(不依赖具体activity)
  6. 前端学习(2856):简单秒杀系统学习之定时器循环显示
  7. 昆山立讯电子工程师_教会徒弟饿死师傅?立讯精密会不会成为第二个富士康
  8. Eclipse中安装Ext插件(Spket IDE)
  9. ERROR 2002 (HY000): Can‘t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock‘
  10. 分解连续自然数的和_小学奥数各年级经典题解题技巧大全——分解因数法(2)...
  11. nutzwk运行后wk-web中生成ehcache.disk.store.dir有什么用,怎么去掉
  12. 华纳传媒和Discovery合并交易将提前完成 华纳CEO将在交易之前辞职
  13. Android学习系列(11)--App列表之拖拽ListView(下)
  14. HDU1850 Being a Good Boy in Spring Festival【Nim博弈】
  15. map mybatis 的字段返回0_mybatis返回map类型数据空值字段不显示(三种解决方法)
  16. SAP BC470 课程中文自学笔记
  17. 南昌工程学院计算机考试题库和答案,南昌工程学院 语试题答案.doc
  18. php浮动广告,JavaScript实现漂浮广告代码的实例总结
  19. 关于PCBLayout的一些具体细节的认识(能力有限,请大家多多指点)
  20. Win10应用设计的那些事儿

热门文章

  1. c语言程序中间改变数组大小,结构中间的可变长度数组 – 为什么这个C代码对gcc有效...
  2. 【Android App】实战项目之使用OpenCV人脸识别实现找人功能(附源码和演示 超详细)
  3. 路由器、集线器、网关、网桥的联系与区别
  4. LSM内核源代码分析与测试(二)
  5. jwt实现一个帐号只能同时在一个设备(端)登录的思路
  6. mysql 军规 (转载)
  7. 离子交换树脂回收贵金属铂钯工艺详解
  8. 音频变声的软件叫什么?这些软件值得收藏
  9. 几种前后端接口的对比:RESTful,GraphQL,APIJSON
  10. HNUCM蓝桥杯Python组寒假第二次练习