博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TOTP:Time-based One-time Password Algorithm(基于时间的一次性密码算法)
阅读量:6192 次
发布时间:2019-06-21

本文共 8908 字,大约阅读时间需要 29 分钟。

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一次性密码算法的扩展。

维基百科:

RFC 6238:

 

项目:

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 asauthors of the code. All rights reserved.Redistribution and use in source and binary forms, with or withoutmodification, is permitted pursuant to, and subject to the licenseterms contained in, the Simplified BSD License set forth in Section4.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); } }}

 运行结果:

 

转载于:https://www.cnblogs.com/dyingbleed/archive/2012/12/05/2803782.html

你可能感兴趣的文章
IT界--值得收藏的10大网站
查看>>
创建Kafka0.8.2生产者与消费者
查看>>
表空间的增删改
查看>>
Cisco 路由器硬件信息查询命令
查看>>
ESXi虚拟机的磁盘格式
查看>>
嘚嘚瑟瑟二二二二二二二
查看>>
2003 域环境下 搭建证书服务器
查看>>
⑨③-不能浪费拥有的年轻资本
查看>>
rsync远程数据备份配置之再次总结
查看>>
Kettle 4.4.2源码分析
查看>>
SQL几个常用函数略解
查看>>
QXDM下查看CDMA短信信息
查看>>
Cisco Packet Tracer模拟器3650交换机新发现
查看>>
Ubuntu编译安装Php,配置时出现:Configure: error: XML configuration could not be found
查看>>
【Touch&input 】指定输入方法类型(11)
查看>>
【SublimeText】【DeleteBlankLines】使用说明
查看>>
java基础-基本数据类型
查看>>
Java基础-Java中的Calendar和Date类
查看>>
网站制作 时光网11月4日又回来了
查看>>
项目资料
查看>>