/**
Copyright (c) 2011 IETF Trust and the persons identified as
authors of the code. All rights reserved. Redistribution and use in source and binary forms, with or without
modification, is permitted pursuant to, and subject to the license
terms contained in, the Simplified BSD License set forth in Section
4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
(http://trustee.ietf.org/license-info).
*/ 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.math.BigInteger;
import java.util.TimeZone; /**
* This is an example implementation of the OATH TOTP algorithm. Visit
* www.openauthentication.org for more information.
*
* @author Johan Rydell, PortWise, Inc.
*/ public class TOTP { private TOTP() {
} /**
* 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
*/
private static byte[] hmac_sha(String crypto, byte[] keyBytes, byte[] text) {
try {
Mac hmac;
hmac = Mac.getInstance(crypto);
SecretKeySpec macKey = new SecretKeySpec(keyBytes, "RAW");
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 converted
byte[] 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 int[] DIGITS_POWER
// 0 1 2 3 4 5 6 7 8
= { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 }; /**
* 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 返回长度 --6
* @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 = hexStr2Bytes(time);
byte[] k = hexStr2Bytes(key);
byte[] hash = hmac_sha(crypto, k, msg); // put selected bytes into result int
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); int otp = binary % DIGITS_POWER[codeDigits]; result = Integer.toString(otp);
while (result.length() < codeDigits) {
result = "0" + result;
}
return result;
} public static void main(String[] args) {
// Seed for HMAC-SHA1 - 20 bytes
String seed = "3132333435363738393031323334353637383930";
// Seed for HMAC-SHA256 - 32 bytes
String seed32 = "3132333435363738393031323334353637383930"
+ "313233343536373839303132";
// Seed for HMAC-SHA512 - 64 bytes
String seed64 = "3132333435363738393031323334353637383930"
+ "3132333435363738393031323334353637383930"
+ "3132333435363738393031323334353637383930" + "31323334";
long T0 = 0;
long X = 30;
long testTime[] = { 59L, 1111111109L, 1111111111L, 1234567890L,
2000000000L, 20000000000L }; String steps = "0";
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
System.out.println("+---------------+-----------------------+"
+ "------------------+--------+--------+");
System.out.println("| Time(sec) | Time (UTC format) "
+ "| Value of T(Hex) | TOTP | Mode |");
System.out.println("+---------------+-----------------------+"
+ "------------------+--------+--------+"); for (int i = 0; i < testTime.length; i++) {
long T = (testTime[i] - T0) / X;
steps = Long.toHexString(T).toUpperCase();
while (steps.length() < 16)
steps = "0" + steps;
String fmtTime = String.format("%1$-11s", testTime[i]);
String utcTime = df.format(new Date(testTime[i] * 1000));
// seed
System.out.print("| " + fmtTime + " | " + utcTime + " | "
+ steps + " |");
System.out.println(generateTOTP(seed, steps, "8", "HmacSHA1")
+ "| SHA1 |"); // seed32
System.out.print("| " + fmtTime + " | " + utcTime + " | "
+ steps + " |");
System.out.println(generateTOTP(seed32, steps, "8",
"HmacSHA256") + "| SHA256 |"); // seed64
System.out.print("| " + fmtTime + " | " + utcTime + " | "
+ steps + " |");
System.out.println(generateTOTP(seed64, steps, "6",
"HmacSHA512") + "| SHA512 |"); System.out.println("+---------------+-----------------------+"
+ "------------------+--------+--------+");
}
} catch (final Exception e) {
System.out.println("Error : " + e);
}
}
}

TOTP算法 基于时间的一次性密码的更多相关文章

  1. TOTP:Time-based One-time Password Algorithm(基于时间的一次性密码算法)

    TOTP:Time-based One-time Password Algorithm(基于时间的一次性密码算法) TOTP - Time-based One-time Password Algori ...

  2. 动态密码卡TOTP算法

    TOTP NET实现:http://googleauthcsharp.codeplex.com/ 引用:http://www.cnblogs.com/wangxin201492/p/5030943.h ...

  3. [信息安全] 4.一次性密码 && 身份认证三要素

    [信息安全]系列博客:http://www.cnblogs.com/linianhui/category/985957.html 在信息安全领域,一般把Cryptography称为密码,而把Passw ...

  4. TOTP算法实现二步验证

    概念 TOTP算法(Time-based One-time Password algorithm)是一种从共享密钥和当前时间计算一次性密码的算法. 它已被采纳为Internet工程任务组标准RFC 6 ...

  5. JavaScript基于时间的动画算法

    转自:https://segmentfault.com/a/1190000002416071 前言 前段时间无聊或有聊地做了几个移动端的HTML5游戏.放在不同的移动端平台上进行测试后有了诡异的发现, ...

  6. Google Cardboard的九轴融合算法——基于李群的扩展卡尔曼滤波

    Google Cardboard的九轴融合算法 --基于李群的扩展卡尔曼滤波 极品巧克力 前言 九轴融合算法是指通过融合IMU中的加速度计(三轴).陀螺仪(三轴).磁场计(三轴),来获取物体姿态的方法 ...

  7. 基于时间的 SQL注入研究

    SQL注入攻击是业界一种非常流行的攻击方式,是由rfp在1998年<Phrack>杂志第54期上的“NT Web Technology Vulnerabilities”文章中首次提出的.时 ...

  8. 如何用一次性密码通过 SSH 安全登录 Linux

    有人说,安全不是一个产品,而是一个过程.虽然 SSH 协议被设计成使用加密技术来确保安全,但如果使用不当,别人还是能够破坏你的系统:比如弱密码.密钥泄露.使用过时的 SSH 客户端等,都能引发安全问题 ...

  9. 2019-9-9:渗透测试,基础学习,phpmyadmin getshell方法,基于时间的盲注,基于报错的注入,笔记

    phpmyadmin getshell方法1,查看是否有导入导出设置 show global variables like '%secure-file-priv%';2,如果secure-file-p ...

随机推荐

  1. Spring有什么缺点?

    Spring有什么缺点如下: 1.jsp中要写很多代码: 2.控制器过于灵活,缺少一个公用控制器: 3.不支持分布式部署.

  2. 【BZOJ2998】Problem A(动态规划)

    [BZOJ2998]Problem A(动态规划) 题面 BZOJ 题解 一个人的成绩范围可以确定为一个区间 这样就变成了 选择若干区间,不重合, 每个区间有个权值,求最大权值和 这样就可直接\(dp ...

  3. 版本控制-Git对象

    Git对象 版本控制在于文件的控制,git的控制方法在于为每个文件生成(key,object)的结构.git利用sha-1加密算法,对每一个文件生成一个唯一的字符序列(明文大小不超过2^64位,对于普 ...

  4. JAVA面试题二

    JAVA 综合面试题 2007-08-12 目录 Java面试题整理 9 Java面向对象 9 1. super()与this()的区别? 9 2. 作用域public,protected,priva ...

  5. 300行Kotlin代码实现的区块链

    使用Kotlin实现的区块链基本逻辑! 源码地址 GitHub仓库 启动方式 启动参数添加 -Dserver.port=8080,启动不同的端口,模拟不同的节点. 假设目前启动了8080和8081两个 ...

  6. UML那些事

    什么是UML?它的全名:Unified Modeling Language,统一建模语言.最近我用到了uml,顺便重温了下这些知识.知乎上有一个讨论话题:uml还有用吗?这个讨论挺有意思的,看完后,受 ...

  7. JavaScript之优化DOM

    优化DOM得从重绘和重排讲起,long long ago... 1.重绘和重排 1.1 重绘和重排是什么 重绘是指一些样式的修改,元素的位置和大小都没有改变: 重排是指元素的位置或尺寸发生了变化,浏览 ...

  8. [转]【安卓笔记】AsyncTask源码剖析

    [转][安卓笔记]AsyncTask源码剖析 http://blog.csdn.net/chdjj/article/details/39122547 前言: 初学AsyncTask时,就想研究下它的实 ...

  9. 自动安装L2tp的脚本

    来自于 https://teddysun.com/448.html #!/usr/bin/env bash PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/ ...

  10. 10个技巧优化PHP程序Laravel 5框架

    10个技巧优化PHP程序Laravel 5框架 性能一直是 Laravel 框架为人诟病的一个点,所以调优 Laravel 程序算是一个必学的技能. 接下来分享一些开发的最佳实践www.itxdl.c ...