翻译[RFC6238] TOTP: Time-Based One-Time Password Algorithm

2023-05-12 20:07:13 浏览数 (2)

在闲暇时间做了一个TOTP相关的开源项目,在项目初步完成之余,我尝试对[RFC6238]文档进行了翻译,供大家参考与查阅,若有不妥之处,还望各位前辈海涵斧正。

[RFC6238] : Time-Based One-Time Password Algorithm

开源项目地址:tick-authenticator

文章概要

代码语言:javascript复制
This document describes an extension of the One-Time Password (OTP) algorithm, namely the HMAC-based One-Time Password (HOTP) algorithm, as defined in RFC 4226, to support the time-based moving factor.

这篇文档主要讲述了关于一次性密码(OTP)的一个扩展算法,此算法是在,RFC4226文档中定义的'基于HMAC的一次性密码算法'基础之上,支持了基于时间移动因子的扩展算法。

代码语言:javascript复制
The HOTP algorithm specifies an event-based OTP algorithm, where the moving factor is an eventcounter.

HOTP算法是一个以事件计数器作为移动因子,基于事件的一次性密码算法。

代码语言:javascript复制
The present work bases the moving factor on a time value.

本文所讲述的算法则是将时间值作为移动因子。

代码语言:javascript复制
A time-based variant of the OTP algorithm provides short-lived OTP values, which are desirable for enhanced security.

这个基于时间的一次性密码生成算法提供了有效时间更短的一次性密码,增强了OTP算法的安全性。

代码语言:javascript复制
The proposed algorithm can be used across a wide range of network applications, from remote Virtual Private Network (V**) access and Wi-Fi network logon to transaction-oriented Web applications.

此算法可以广泛的应用于互联网应用之中,包括远程虚拟专用网络(V**)的访问控制,Wi-Fi网络登录以及面向交易的网络应用等等。

代码语言:javascript复制
The authors believe that a common and shared algorithm will facilitate adoption of two-factor authentication on the Internet by enabling interoperability across commercial and open-source implementations.

作者相信通过商用和开源的算法实现,一个通用的共享算法将会促进互联网上更多的人接触并使用到双因素身份认证算法。

介绍

概说

代码语言:javascript复制
This document describes an extension of the One-Time Password (OTP) algorithm, namely the HMAC-based One-Time Password (HOTP) algorithm, as defined in [RFC4226], to support the time-based moving factor.

本文主要描述了一次性密码(OTP)的一个扩展算法,此算法是支持将时间作为移动因子的一个基于HMAC的一次性加密算法。

背景

代码语言:javascript复制
As defined in [RFC4226], the HOTP algorithm is based on the HMAC-SHA-1 algorithm (as specified in [RFC2104]) and applied to an increasing counter value representing the message in the HMAC computation.

在4226文档中描述中,HOTP算法是基于HMAC-SHA-1算法并用一个自增的计数值器来作为HMAC计算中的消息。

代码语言:javascript复制
Basically, the output of the HMAC-SHA-1 calculation is truncated to obtain user-friendly values:

基本上,HMAC-SHA-1的计算输出结果都会截取为一串对用户友好的值。

代码语言:javascript复制
HOTP(K,C) = Truncate(HMAC-SHA-1(K,C))
代码语言:javascript复制
where Truncate represents the function that can convert an HMAC-SHA-1 value into an HOTP value. K and C represent the shared secret and counter value; see [RFC4226] for detailed definitions.

Truncate函数表示它能够将HMAC-SHA-1的计算结果转换成HOTP的结果值。 K表示共享密钥,C表示计数值,详情请看[RFC4226]。

代码语言:javascript复制
TOTP is the time-based variant of this algorithm, where a value T, derived from a time reference and a time step, replaces the counter C in the HOTP computation.

TOTP算法是上述算法基于时间的变体,使用通过时间戳和时间步长推导出来的数值T来代替原有HOTP算法中的计数器C。

代码语言:javascript复制
TOTP implementations MAY use HMAC-SHA-256 or HMAC-SHA-512 functions, based on SHA-256 or SHA-512 [SHA2] hash functions, instead of the HMAC-SHA-1 function that has been specified for the HOTP computation in [RFC4226].

TOTP算法的实现可以采用HMAC-SHA-256或HMAC-SHA-512函数,用此来代替原有HOTP计算中采用的HMAC-SHA-1方案。

算法要求

代码语言:javascript复制
This section summarizes the requirements taken into account for designing the TOTP algorithm.

这一部分概括性的总结了,在设计TOTP算法时需要考虑的方面。

代码语言:javascript复制
R1: The prover (e.g., token, soft token) and verifier (authentication or validation server) MUST know or be able to derive the current Unix time (i.e., the number of seconds elapsed since midnight UTC of January 1, 1970) for OTP generation.  See [UT] for a more detailed definition of the commonly known "Unix time".  The precision of the time used by the prover affects how often the clock synchronization should be done; see Section 6.

R1: 证明者和验证者都必须知道或者能够根据Unix时间推导得出OTP。证明者所提供的时间精度将会影响到需要多久进行一次时钟同步,详见第六部分。

代码语言:javascript复制
R2: The prover and verifier MUST either share the same secret or the knowledge of a secret transformation to generate a shared secret.

R2: 证明者和验证者必须分享相同的密钥或者密钥生成转换的方法。

代码语言:javascript复制
R3: The algorithm MUST use HOTP [RFC4226] as a key building block.

R3: 算法必须使用HOTP算法来进行关键块构建。

代码语言:javascript复制
R4: The prover and verifier MUST use the same time-step value X.

R4: 证明者和验证者必须使用相同的时间步长X。

代码语言:javascript复制
R5: There MUST be a unique secret (key) for each prover.

R5: 对于每一个证明者必须要分配唯一的密钥Key。

代码语言:javascript复制
R6: The keys SHOULD be randomly generated or derived using key derivation algorithms.

R6: 密钥Key应该是随机生成的或导出密钥推导算法。

代码语言:javascript复制
R7: The keys MAY be stored in a tamper-resistant device and SHOULD be protected against unauthorized access and usage.

R7: 密钥key可以存放在防篡改的设备之中并防止未经授权的非法访问。

TOTP算法

代码语言:javascript复制
This variant of the HOTP algorithm specifies the calculation of a one-time password value, based on a representation of the counter as a time factor.

TOTP算法是用时间因子来表示计数器的一种计算一次性密码的HOTP算法的变体。

释义

代码语言:javascript复制
o  X represents the time step in seconds (default value X = 30 seconds) and is a system parameter.

o  T0 is the Unix time to start counting time steps (default value is 0, i.e., the Unix epoch) and is also a system parameter.
  • X表示以秒为单位的时间步长(默认为30秒),它是一个系统参数。
  • T0是开始计步的起始Unix时间(默认是0,即)也是一个系统参数。

描述

代码语言:javascript复制
Basically, we define TOTP as TOTP = HOTP(K, T), where T is an integer and represents the number of time steps between the initial counter time T0 and the current Unix time.

一般而言,我们将TOTP定义为TOTP = HOTP(K, T),其中T是一个整数,代表了在初始时间T0和当前Unix时间之间的时间步长。

代码语言:javascript复制
More specifically, T = (Current Unix time - T0) / X, where the default floor function is used in the computation.

更具体的说,T = (Current Unix time - T0) / X,默认在计算时向下取整。

代码语言:javascript复制
For example, with T0 = 0 and Time Step X = 30, T = 1 if the current Unix time is 59 seconds, and T = 2 if the current Unix time is 60 seconds.

比如,T0=0,X=30时,当前Unix时间为59秒那么T=1,当前Unix时间为60秒时,那么T=2。

代码语言:javascript复制
The implementation of this algorithm MUST support a time value T larger than a 32-bit integer when it is beyond the year 2038. The value of the system parameters X and T0 are pre-established during the provisioning process and communicated between a prover and verifier aspart of the provisioning step. The provisioning flow is out of scope of this document; refer to [RFC6030] for such provisioning container specifications.

算法的实现必须支持,当时间T超过2038年后,时间数值大于32位整数这种情况。系统参数X和T0是预先就确定好的了,作为准备步骤的一部分,已经在客户端和服务端进行了同步。相关的同步流程已超出了本文档的表述范围,详情请见[RFC6030]。

基于安全的考量

常规的

代码语言:javascript复制
The security and strength of this algorithm depend on the properties of the underlying building block HOTP, which is a construction based on HMAC [RFC2104] using SHA-1 as the hash function.

算法的安全性和可靠程度依赖于用于构建HOTP块的属性参数。它是在构造HMAC时使用的SHA-1作为哈希函数。

代码语言:javascript复制
The conclusion of the security analysis detailed in [RFC4226] is that, for all practical purposes, the outputs of the dynamic truncation on distinct inputs are uniformly andindependently distributed strings.

通过[RFC4226]中详尽的安全性分析结论得知,在所有真实场景下,针对不同的输入,所得到的输出结果截断,都是相互独立且没有必然联系的字符串。

代码语言:javascript复制
The analysis demonstrates that the best possible attack against the HOTP function is the brute force attack.

分析表明,针对HOTP最有可能的破解方式就是暴力破解。

代码语言:javascript复制
As indicated in the algorithm requirement section, keys SHOULD be chosen at random or using a cryptographically strong pseudorandom generator properly seeded with a random value.

如算法实现中要求的那样,密钥key应当选择随机值或者通过设置了合理随机种子安全的强伪随机数生成器生成随机数。

代码语言:javascript复制
Keys SHOULD be of the length of the HMAC output to facilitate interoperability.

密钥的长度应当与HMAC的输出长度一致,已达到复用。

代码语言:javascript复制
We RECOMMEND following the recommendations in [RFC4086] for all pseudorandom and random number generations. The pseudorandom numbers used for generating the keys SHOULD successfully pass the randomness test specified in [CN], or a similar well-recognized test.

对于伪随机数以及随机数生成器相关的事项,建议遵从[RFC4086]的规则定义。用于生成密钥的伪随机数要求能够通过在[CN]中指定的随机性测验或者其他公认的测试。

代码语言:javascript复制
All the communications SHOULD take place over a secure channel, e.g., Secure Socket Layer/Transport Layer Security (SSL/TLS) [RFC5246] or IPsec connections [RFC4301].

所有通信应该建立在安全通道之上,例如安全套接字层/传输层安全或IPsec连接。

代码语言:javascript复制
We also RECOMMEND storing the keys securely in the validation system, and, more specifically, encrypting them using tamper-resistant hardware encryption and exposing them only whenrequired: for example, the key is decrypted when needed to verify an OTP value, and re-encrypted immediately to limit exposure in the RAM to a short period of time.

我们也同样建议将密钥安全地存放在认证系统之中,更加具体的讲,使用防篡改的硬件来加密客户端的密钥。仅当,真的有必要时才将其暴露出来,比如在认证一次性密钥是否正确是,需要对密钥进行解密,当此操作完成之后便立即重新加密,以此来最大限度地缩短密钥明文变量暴露在内存中时间。

代码语言:javascript复制
The key store MUST be in a secure area, to avoid, as much as possible, direct attack on the validation system and secrets database. Particularly, access to the key material should be limited to programs and processes required by the validation system only.

密钥必须存放在安全可靠的地方,以尽可能的避免对认证服务器系统和存放密钥的数据库的直接攻击。 特别是,获取密钥信息这一操作应当被限制在验证系统所必须的程序或相关执行过程之中。

验证和时间步长

代码语言:javascript复制
An OTP generated within the same time step will be the same. When an OTP is received at a validation system, it doesn't know a client's exact timestamp when an OTP was generated. The validation system may typically use the timestamp when an OTP is received for OTP comparison.

在相同的时间步数内生成的一次性密码结果是一样的。当验证服务器接收到一个一次性密码时,它并不知道客户端具体是在何时生成的这个一次性密码。验证服务器或许会使用接收到客户端密码的这个时间来生成密码并与客户端密码进行比较。

代码语言:javascript复制
Due to network latency, the gap (as measured by T, that is, the number of time steps since T0) between the time that the OTP was generated and the time that the OTP arrives at the receiving system may be large. The receiving time at the validation system and the actual OTP generation may not fall within the same time-step window that produced the same OTP.

但由于网络延迟,客户端生成出一次性密码的时间和服务端接收到的时间差距(用T进行计量,它是从T0开始的时间时间步数)可能会很大。验证服务器接收到的时间和实际生成一次性密码的时间有可能不会落在同一个时间计步窗口下,由此可能会产生两个不一致的一次性密码。

代码语言:javascript复制
When an OTP is generated at the end of a time-step window, the receiving time most likely falls into the next time-step window. A validation system SHOULD typically set a policy for an acceptable OTP transmission delay window for validation.

当客户端生成一次性密码的时间在时间计步窗口靠后的位置,那么服务端收到密码的时间就很有可能会落到下一个计步窗口之中。验证服务器通常要为因传输延迟而不能匹配有效的一次性密码的情形设置相应的延时窗口来进行验证。

代码语言:javascript复制
The validation system should compare OTPs not only with the receiving timestamp but also the past timestamps that are within the transmission delay. A larger acceptable delay window would expose a larger window for attacks. We RECOMMEND that at most one time step is allowed as the network delay.

这样的话,认证系统就不应当用接收到一次性密码的时间来生成比较密码了,还需要将在传输时延内的那些密码也要包含进去进行验证。越大的可接受时延窗口会暴露出更大的攻击窗口。所以我们建议最多使用一个时间步长来应对网络时延问题。

代码语言:javascript复制
The time-step size has an impact on both security and usability. A larger time-step size means a larger validity window for an OTP to be accepted by a validation system. There are implications for using a larger time-step size, as follows:

时间步长影响着系统的安全性和可用性。一个更大的时间步长意味着认证系统要设置更大的一次性密码的可接受窗口。使用更大的时间步长会关联到以下几个方面:

代码语言:javascript复制
First, a larger time-step size exposes a larger window to attack. When an OTP is generated andexposed to a third party before it is consumed, the third party can consume the OTP within the time-step window.

首先,更大的时间步长会暴露出更大的可攻击窗口。当一次性密码生成完成并在失效之前暴露给第三方, 那么第三方就能够在这个时间窗口内继续使用这个一次性密码。

代码语言:javascript复制
We RECOMMEND a default time-step size of 30 seconds. This default value of 30 seconds isselected as a balance between security and usability.

我们建议默认的时间步长为30秒。将其设置为30秒是综合考虑了安全性和可用性的结果。

代码语言:javascript复制
Second, the next different OTP must be generated in the next time-step window. A user must wait until the clock moves to the next time-step window from the last submission. The waiting time may not be exactly the length of the time step, depending on when the last OTP was generated.

第二,下一个不同的一次性密码只能在下一个时间窗口下才能生成。一个用户必须等到时钟到了下一个时间窗口内才能进行新的提交。这个等待时间不一定等于时间步长,它依赖于最后一次生成一次性密码的时间。

代码语言:javascript复制
For example, if the last OTP was generated at the halfway point in a time-step window, the waiting time for the next OTP is half the length of the time step. In general, a larger time-step window means a longer waiting time for a user to get the next valid OTP after the lastsuccessful OTP validation.

比如,如果最后一次生成一次性密码的时间是在时间窗口的一半的位置,那么等待生成下一个一次性密码的时间就会是步长的一半。一般而言,越大的时间步长意味着用户需在上一个成功的一次性密码验证之后,需要等待更长的时间才能够生成下一个合法的一次性密码来进行新的验证。

代码语言:javascript复制
A too-large window (for example, 10 minutes) most probably won't be suitable for typical Internet login use cases; a user may not be able to get the next OTP within 10 minutes and therefore will have to re-login to the same site in 10 minutes.

一个超大的窗口,比如十分钟,很可能不适合典型的互联网用户的登录需求。用户无法在十分钟之内获取到下一个一次性密码,所以就让他等十分钟再来登陆吗?

代码语言:javascript复制
Note that a prover may send the same OTP inside a given time-step window multiple times to a verifier. The verifier MUST NOT accept the second attempt of the OTP after the successful validation has been issued for the first OTP, which ensures one-time only use of an OTP.

注意,认证者可以在相同的时间窗口内多次发送相同的一次性密码到服务器上来进行认证。所以在同一个时间窗口下服务器在第一个一次性密码验证成功之后就不能在接受验证第二个一次性密码了,这也确保了一个时间内只使用一个一次性密码(否则一个30秒的时间窗口,暴力轮接口肯定能把6位密码给攻破)。

同步校准机制

代码语言:javascript复制
Because of possible clock drifts between a client and a validation server, we RECOMMEND that the validator be set with a specific limit to the number of time steps a prover can be "out of synch" before being rejected.

由于可能存在客户端时钟和认证服务器的时钟不同步的问题,我们建议验证者在拒绝掉客户端'错误的'认证之前,通过设置步长的方式对不同步的时间进行校准。

代码语言:javascript复制
This limit can be set both forward and backward from the calculated time step on receipt ofthe OTP value. If the time step is 30 seconds as recommended, and the validator is set to onlyaccept two time steps backward, then the maximum elapsed time drift would be around 89seconds, i.e., 29 seconds in the calculated time step and 60 seconds for two backward timesteps.

这个限制可以是,从收到OTP值时的计算时间开始,向前和向后设置以步长为单位的时间,如果时间步长设置为30秒,验证者要向后设置两个时间步长,如果这样的话最大的漂移时间就会在89秒左右(允许客户端与服务器有89秒的误差),即用于计算的那个时间步长内剩余的29秒和向后的两个时间步长的60秒。

代码语言:javascript复制
This would mean the validator could perform a validation against the current time and then two further validations for each backward step (for a total of 3 validations).  Upon successful validation, the validation server can record the detected clock drift for the token in terms of the number of time steps.  When a new OTP is received after this step, the validator can validate the OTP with the current timestamp adjusted with the recorded number of time-step clock drifts
for the token.

这意味着验证器会用当前时间窗口执行验证,也会用由此向后的两个时间窗口再进行验证(一共是三个时间窗口的验证)。认证成功之后,认证服务器可以记录所侦测到的时钟漂移。在此步骤之后,当收到一个新的一次性密码时,认证者可以通过当前时间和之前记录的时钟漂移步长得出的一个校准后的时间来验证客户端的一次性密码。

代码语言:javascript复制
Also, it is important to note that the longer a prover has not sent an OTP to a validation system, the longer (potentially) the accumulated clock drift between the prover and the verifier. In such cases, the automatic resynchronization described above may not work if the drift exceeds the allowed threshold. Additional authentication measures should be used to safely authenticate the prover and explicitly resynchronize the clock drift between the prover and the validator.

同样,需要注意的是,客户端未向服务器发送一次性密码的时间越长,由此积累的时钟漂移就有可能会越来越大。在这样的场景下,如果漂移量大于程序所允许的阈值的话,那么自动校准功能可能就会失效。这时就应该使用其他的认证方式进行安全身份验证,并显式地校准客户端和服务端的时钟漂移。

0 人点赞