TOTP:Time-based One-time Password Algorithm(基于时间的一次性密码算法)
TOTP:Time-based One-time Password Algorithm(基于时间的一次性密码算法)
TOTP - Time-based One-time Password Algorithm is an extension of the HMAC-based One Time Password algorithm HOTP to support a time based moving factor.
TOTP(基于时间的一次性密码算法)是支持时间作为动态因素基于HMAC一次性密码算法的扩展。
维基百科:http://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm
RFC 6238:http://tools.ietf.org/html/rfc6238
项目:
Google Authenticator
项目地址:http://code.google.com/p/google-authenticator/
运行截图:

实现:
1)Prover与Verifier之间必须时钟同步;
2)Prover与Verifier之间必须共享密钥;
3)Prover与Verifier之间必须使用相同的时间步长
算法:
K 共享密钥
T 时间
T0 开始计数的时间步长
X 时间步长
TOTP = Truncate(HMAC-SHA-1(K, (T - T0) / X))
代码示例:

/**
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
* @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));
System.out.print("| " + fmtTime + " | " + utcTime + " | "
+ steps + " |");
System.out.println(generateTOTP(seed, steps, "8", "HmacSHA1")
+ "| SHA1 |");
System.out.print("| " + fmtTime + " | " + utcTime + " | "
+ steps + " |");
System.out.println(generateTOTP(seed32, steps, "8",
"HmacSHA256") + "| SHA256 |");
System.out.print("| " + fmtTime + " | " + utcTime + " | "
+ steps + " |");
System.out.println(generateTOTP(seed64, steps, "8",
"HmacSHA512") + "| SHA512 |"); System.out.println("+---------------+-----------------------+"
+ "------------------+--------+--------+");
}
} catch (final Exception e) {
System.out.println("Error : " + e);
}
}
}

运行结果:

iOS 开发讨论群:82873648

本作品采用知识共享署名-非商业性使用 3.0 许可协议进行许可。
转载请署名李震(博客地址:http://www.cnblogs.com/dyingbleed/),且不得用于商业目的。
TOTP:Time-based One-time Password Algorithm(基于时间的一次性密码算法)的更多相关文章
- TOTP算法 基于时间的一次性密码
/** Copyright (c) 2011 IETF Trust and the persons identified as authors of the code. All rights rese ...
- 翻译[RFC6238] TOTP: Time-Based One-Time Password Algorithm
在闲暇时间做了一个TOTP相关的开源项目,在项目初步完成之余,我尝试对[RFC6238]文档进行了翻译,供大家参考与查阅,若有不妥之处,还望各位前辈海涵斧正. [RFC6238] : Time-Bas ...
- [Swift]LeetCode981. 基于时间的键值存储 | Time Based Key-Value Store
Create a timebased key-value store class TimeMap, that supports two operations. 1. set(string key, s ...
- mahout demo——本质上是基于Hadoop的分步式算法实现,比如多节点的数据合并,数据排序,网路通信的效率,节点宕机重算,数据分步式存储
摘自:http://blog.fens.me/mahout-recommendation-api/ 测试程序:RecommenderTest.java 测试数据集:item.csv 1,101,5.0 ...
- 普林斯顿大学算法课 Algorithm Part I Week 3 排序算法复杂度 Sorting Complexity
计算复杂度(Computational complexity):用于研究解决特定问题X的算法效率的框架 计算模型(Model of computation):可允许的操作(Allowable oper ...
- 基于视觉信息的网页分块算法(VIPS) - yysdsyl的专栏 - 博客频道 - CSDN.NET
基于视觉信息的网页分块算法(VIPS) - yysdsyl的专栏 - 博客频道 - CSDN.NET 于视觉信息的网页分块算法(VIPS) 2012-07-29 15:22 1233人阅读 评论(1) ...
- mysql 开发进阶篇系列 43 逻辑备份与恢复(mysqldump 的基于时间和位置的不完全恢复)
一. 概述 在上篇讲到了逻辑备份,使用mysqldump工具来备份一个库,并使用完全恢复还原了数据库.在结尾也讲到了误操作是不能用完全恢复的.解决办法是:我们需要恢复到误操作之前的状态,然后跳过误操作 ...
- 基于时间的 SQL注入研究
SQL注入攻击是业界一种非常流行的攻击方式,是由rfp在1998年<Phrack>杂志第54期上的“NT Web Technology Vulnerabilities”文章中首次提出的.时 ...
- SQL基于时间的盲注过程
0x00 前言 由于要使用到基于时间的盲注,但是我觉得基于时间的盲注其实就是基于布尔的盲注的升级版,所以我想顺便把基于布尔的盲注分析总结了: 首先我觉得基于时间的盲注和基于布尔的盲注的最直观的差别就是 ...
随机推荐
- 【翻译自mos文章】在一次失败的 'Shutdown Immediate'之后,数据库job 不能执行。
在一次失败的 'Shutdown Immediate'之后.数据库job 不能执行. 參考原文: Database Jobs Do Not Run After a Failed 'Shutdown I ...
- Pairwise
FCC题目:找到你的另一半 有一个能力数组[7,9,11,13,15],按照最佳组合值为20来计算,只有7+13和9+11两种组合.而7在数组的索引为0,13在数组的索引为3,9在数组的索引为1,11 ...
- 使用nmonchart把.nmon文件转换成html
转载:https://blog.csdn.net/zd470015321/article/details/68923280 我的环境 :centos6.6 下载地址 nmon: http://nmon ...
- tableview的两个重用cell方法
今天在学习IAP的时候无意间看到原来 tableView: cellForRowAtIndexPath:方法中有两个获得重用cell的方法,一直以来都是用 UITableViewCell *cel ...
- ASP.NET Core Kestrel 随机404错误
一.Bug 出现 最近遇到一个很诡异的bug,Visual Studio 2017调试ASP.NET Core 2.2 Web程序的时候,随机性的出现404错误.如下图 事实上这个css文件是存在的, ...
- test推荐到极客头条002
test推荐到极客头条002test推荐到极客头条002test推荐到极客头条002test推荐到极客头条002test推荐到极客头条002test推荐到极客头条002test推荐到极客头条002te ...
- java线程-synchronized实现可见性代码
以下是一个普通线程代码: package com.Sychronized; public class SychronizedDemo { //共享变量 private boolean ready=fa ...
- 解析theme()
drupal_render()只是对theme()的调用做了包装,真正做任务的还是theme(). function theme($hook, $variables = array()) { ... ...
- 携程实时大数据平台演进:1/3 Storm应用已迁到JStorm
携程大数据平台负责人张翼分享携程的实时大数据平台的迭代,按照时间线介绍采用的技术以及踩过的坑.携程最初基于稳定和成熟度选择了Storm+Kafka,解决了数据共享.资源控制.监控告警.依赖管理等问题之 ...
- P2P原理
简单介绍 前面文章在分布式计算泛型中介绍过P2P泛型.他是一种是一种无中心server的对等网络泛型. P2P即Peer-to-Peer的缩写.翻译为点对点或者端对端.就是我们常说的对等计算. P2P ...