OTP,HOTP,TOTP基本原理

名词解释

OTP 是 One-Time Password的简写,表示一次性密码。

HOTP 是HMAC-based One-Time Password的简写,表示基于HMAC算法加密的一次性密码。

TOTP 是Time-based One-Time Password的简写,表示基于时间戳算法的一次性密码。

基本介绍

  TOTP 是时间同步,基于客户端的动态口令和动态口令验证服务器的时间比对,一般每60秒产生一个新口令,要求客户端和服务器能够十分精确的保持正确的时钟,客户端和服务端基于时间计算的动态口令才能一致。

  HOTP 是事件同步,通过某一特定的事件次序及相同的种子值作为输入,通过HASH算法运算出一致的密码。

原理介绍

OTP基本原理

计算OTP串的公式

OTP(K,C) = Truncate(HMAC-SHA-1(K,C))

其中,

K表示秘钥串;

C是一个数字,表示随机数;

HMAC-SHA-1表示使用SHA-1做HMAC;

Truncate是一个函数,就是怎么截取加密后的串,并取加密后串的哪些字段组成一个数字。

对HMAC-SHA-1方式加密来说,Truncate实现如下。

  • HMAC-SHA-1加密后的长度得到一个20字节的密串;
  • 取这个20字节的密串的最后一个字节,取这字节的低4位,作为截取加密串的下标偏移量;
  • 按照下标偏移量开始,获取4个字节,按照大端方式组成一个整数;
  • 截取这个整数的后6位或者8位转成字符串返回。

Java代码实现

 public static String generateOTP(String K,
                                      String C,
                                      String returnDigits,
                                      String crypto){
        int codeDigits = Integer.decode(returnDigits).intValue();
        String result = null;

        // K是密码
        // C是产生的随机数
        // crypto是加密算法 HMAC-SHA-1
        byte[] hash = hmac_sha(crypto, K, C);
        // hash为20字节的字符串

        // put selected bytes into result int
        // 获取hash最后一个字节的低4位,作为选择结果的开始下标偏移
        int offset = hash[hash.length - 1] & 0xf;

        // 获取4个字节组成一个整数,其中第一个字节最高位为符号位,不获取,使用0x7f
        int binary =
                ((hash[offset] & 0x7f) << 24) |
                ((hash[offset + 1] & 0xff) << 16) |
                ((hash[offset + 2] & 0xff) << 8) |
                (hash[offset + 3] & 0xff);
        // 获取这个整数的后6位(可以根据需要取后8位)
        int otp = binary % 1000000;
        // 将数字转成字符串,不够6位前面补0
        result = Integer.toString(otp);
        while (result.length() < codeDigits) {
            result = "0" + result;
        }
        return result;
    }

返回的结果就是看到一个数字的动态密码。

HOTP基本原理

知道了OTP的基本原理,HOTP只是将其中的参数C变成了随机数

公式修改一下

HOTP(K,C) = Truncate(HMAC-SHA-1(K,C))

HOTP: Generates the OTP for the given count

即:C作为一个参数,获取动态密码。

HOTP的python代码片段:

class HOTP(OTP):
    def at(self, count):
        """
        Generates the OTP for the given count
        @param [Integer] count counter
        @returns [Integer] OTP
        """
        return self.generate_otp(count)

一般规定HOTP的散列函数使用SHA2,即:基于SHA-256 or SHA-512 [SHA2] 的散列函数做事件同步验证;

TOTP基本原理

TOTP只是将其中的参数C变成了由时间戳产生的数字。

TOTP(K,C) = HOTP(K,C) = Truncate(HMAC-SHA-1(K,C))

不同点是TOTP中的C是时间戳计算得出。

C = (T - T0) / X;

T 表示当前Unix时间戳

T0一般取值为 0.

X 表示时间步数,也就是说多长时间产生一个动态密码,这个时间间隔就是时间步数X,系统默认是30秒;

例如:

T0 = 0;

X = 30;

T = 30 ~ 59, C = 1; 表示30 ~ 59 这30秒内的动态密码一致。

T = 60 ~ 89, C = 2; 表示30 ~ 59 这30秒内的动态密码一致。

不同厂家使用的时间步数不同;

  • 阿里巴巴的身份宝使用的时间步数是60秒;
  • 宁盾令牌使用的时间步数是60秒;
  • Google的 身份验证器的时间步数是30秒;
  • 腾讯的Token时间步数是60秒;

TOTP的python代码片段:

class TOTP(OTP):
    def __init__(self, *args, **kwargs):
        """
        @option options [Integer] interval (30) the time interval in seconds
            for OTP This defaults to 30 which is standard.
        """
        self.interval = kwargs.pop(‘interval‘, 30)
        super(TOTP, self).__init__(*args, **kwargs)
    def now(self):
        """
        Generate the current time OTP
        @return [Integer] the OTP as an integer
        """
        return self.generate_otp(self.timecode(datetime.datetime.now()))

    def timecode(self, for_time):
        i = time.mktime(for_time.timetuple())
        return int(i / self.interval)

代码说明

self.interval 是时间步数X

datetime.datetime.now()为当前的Unix时间戳

timecode表示(T - T0) / X,即获取获取动态密码计算的随机数。

TOTP 的实现可以使用HMAC-SHA-256或者HMAC-SHA-512散列函数;

python的otp实现

https://pypi.python.org/pypi/pyotp

https://github.com/pyotp/pyotp

基于pyotp的简单应用

>>> import base64
>>> base64.b32encode(‘This is my secret key‘)
‘KRUGS4ZANFZSA3LZEBZWKY3SMV2CA23FPE======‘
>>> secretKey = base64.b32encode(‘This is my secret key‘)
>>> import pyotp
>>> totp = pyotp.TOTP(secretKey)
>>> totp.now()
423779

程序的简单说明

加载base64的模块,将我的秘钥做一下base32的加密,加载pyotp模块,otp使用base32加密后的秘钥传作为种子,生成随机数字验证的。

可以使用pyotp和expect一起实现基于google authenticator的自动登录(免去每次双认证,输入密码和动态密码)。

pyotp的TOTP的使用说明(官网)

totp = pyotp.TOTP(‘base32secret3232‘)
totp.now() # => 492039

# OTP verified for current time
totp.verify(492039) # => True
time.sleep(30)
totp.verify(492039) # => False

pyotp的HOTP的使用说明(官网) 

hotp = pyotp.HOTP(‘base32secret3232‘)
hotp.at(0) # => 260182
hotp.at(1) # => 55283
hotp.at(1401) # => 316439

# OTP verified with a counter
hotp.verify(316439, 1401) # => True
hotp.verify(316439, 1402) # => False

使用场景

  • 服务器登录动态密码验证(如阿里云ECS登录,腾讯机房服务器登录等);
  • 公司VPN登录双因素验证;
  • 网络接入radius动态密码;
  • 银行转账动态密码;
  • 网银、网络游戏的实体动态口令牌;
  • 等动态密码验证的应用场景。

市面上基于HOTP的产品

Google基于TOTP的开源实现

https://github.com/google/google-authenticator

RFC6238中TOTP基于java代码的实现。

golang的一个otp做的不错的实现

https://github.com/gitchs/gootp

RFC参考

RFC 4226 One-Time Password and HMAC-based One-Time Password.

RFC 6238 Time-based One-Time Password.

RFC 2104 HMAC Keyed-Hashing for Message Authentication.

Done.

时间: 2024-08-13 22:02:55

OTP,HOTP,TOTP基本原理的相关文章

动态令牌-(OTP,HOTP,TOTP)-基本原理

名词解释和基本介绍 OTP 是 One-Time Password的简写,表示一次性密码. HOTP 是HMAC-based One-Time Password的简写,表示基于HMAC算法加密的一次性密码. 是事件同步,通过某一特定的事件次序及相同的种子值作为输入,通过HASH算法运算出一致的密码. TOTP 是Time-based One-Time Password的简写,表示基于时间戳算法的一次性密码. 是时间同步,基于客户端的动态口令和动态口令验证服务器的时间比对,一般每60秒产生一个新口

TOTP 介绍及基于C#的简单实现

TOTP 介绍及基于C#的简单实现 Intro TOTP 是基于时间的一次性密码生成算法,它由?RFC 6238?定义.和基于事件的一次性密码生成算法不同?HOTP,TOTP 是基于时间的,它和 HOTP 具有如下关系: TOTP = HOTP(K, T) HOTP(K,C) = Truncate(HMAC-SHA-1(K,C)) 其中: T:T = (Current Unix time - T0) / X, T0 = 0,X = 30 K:客户端和服务端的共享密钥,不同的客户端的密钥各不相同.

双因子认证解决方案

什么叫双因子认证? 通俗的讲,一般的认证方式都是用户名/密码的方式,也就是只有密码这一个因子来作认证,双因子无非是增加一个因子,增强认证的安全性. 常见解决方案 短信方式 邮件方式 电话语音方式 TOTP解决方案 前三种方案,其实都大同小异.Server端通过某种算法生成一段随机密码,通过短信.邮件或者电话的方式传递给用户,用户把随机密码作为登录的凭证传递给Server,Server验证通过之后,就完成了一次双因子认证.但是短信和电话语音对于运营公司是有一定的成本的,除此之外有些非互联网的应用可

The YubiKey NEO

The YubiKey NEO The YubiKey line of hardware one-time-password (OTP) generators has been on the market for a few years now—in 2010, we looked at the earlier generation of devices when support for them came to Fedora. But since that time, several upda

The YubiKey NEO -- Smartcard features

Smartcard features on the YubiKey NEO YubiKeys are a line of small and low-cost hardware security tokens popular for their one-time password (OTP) functionality. While the basic YubiKey model is limited to generating OTPs when plugged into a USB port

SpookyOTP

https://pypi.python.org/pypi/SpookyOTP/1.1.1 SpookyOTP 1.1.1 Downloads ↓ A lightweight Python 2/3 package for handling HOTP/TOTP (Google Authenticator) authentication. SpookyOTP========= Lightweight Python package for TOTP/HOTP (Google Authenticator)

Security+认证考试心得分享(三)

经验: 因为从事安全方面工作,这次考试复习不太过关,吃老底比较多哈,不过通过对security+学习和考试还是了解了很多新的知识点,还是非常有益处的. 1)复习过程:课本一遍.习题册自己做一遍,习题册看老师视频讲解一遍,讲课实际上算是没有听.个人感觉课本基本上都是核心考点,老师讲课里面会包含很多拓展知识,在考试中也会遇到不少,习题册对了解考试出题方法以及常考的知识点非常有价值,所以时间充裕的同学最好这三样都要跟上,时间不太充足的至少课本和习题册要看差不多,总的来说全心投入去复习两周时间足够,拖延

odoo12之应用:一、双因子验证(Two-factor authentication, 2FA)(HOTP,TOTP)附源码

前言 双因子认证:双因子认证(2FA)是指结合密码以及实物(信用卡.SMS手机.令牌或指纹等生物标志)两种条件对用户进行认证的方法.--百度百科 跟我一样"老"的网瘾少年想必一定见过买点卡后上面送的密保(类似但不完全一样),还有"将军令",以及网银的网盾,是一种二次验证的机制:它通常是6位的数字,每次使用后(HOTP)或者一定时间后(TOTP)都将会刷新,大大加大了用户的安全性,OTP(One-Time Password)分为HOTP(HMAC-based One-

NetScaler OTP双因子身份认证登录演示

NetScaler OTP 应用场景 NetScaler OTP(one time password)是双因子身份证的一种,利用用户名密码+6位时间型令牌认证码,完成身份认证. 在以前的双因子解决方案中NetScalerGateway需要与第三方 Radius服务器集成,实现双因子认证.对于客户来说,需要额外支付双因子身份认证的费用,提高了解决方案成本. NetScaler OTP解决方案利用NetScaler 源生功能,配合手机APP  google authenticator,不需要其他成本