了解基于时间的一次性密码算法的工作原理

2020-09-01 18:49:16

网络安全一直是我的薄弱环节,在第n次设置Authy之后,现在似乎是深入研究并弄清楚这些基于时间的一次性密码算法到底是如何工作的好时机。

在最高级别,您在这些应用程序上看到的密码是使用TOTP(基于时间的一次性密码)算法创建的。密码是通过组合来自您正在进行身份验证的服务的密钥和当前时间来生成的。这就是为什么代码总是在几秒钟后失效。

如果您自己安装了这些应用程序,您可能会记得在安装过程中必须扫描某个地方的二维码。这就是将密钥传输到设备的安全钥匙链存储。此算法与您的SIM卡、蜂窝网络提供商或手机的制造商/型号无关,这使得它比向用户发送验证码更可取。算法只考虑当前时间和共享密钥。

每当您在支持TOTP的服务上创建新帐户时,它们都会为您的用户帐户生成唯一的密码。然后,下次您登录时,网站将运行与客户端生成密码相同的算法。如果来自客户端的密码与服务器生成的密码匹配,则用户通过身份验证,双因素身份验证过程完成。

我总是发现,直接查看代码会更容易理解这样的概念。让我们看看要从头开始实现TOTP服务需要做些什么。

TOTP建立在称为基于HMAC的一次性密码算法(HOTP)的基本算法之上,我们首先需要了解该算法。

如果TOTP和HOTP/HMAC之间的区别还不完全清楚,请不要担心。TOTP和HOTP实现之间的主要区别涉及计数器属性。

HOTP的计数器通常是事件驱动的-例如,按下按钮就会更改计数器值。

首先,我们将根据时间戳创建计数器。为了避免任何额外的复杂性,我们将只使用与时区无关的从纪元开始的时间。

简单地说,此计算的结果是计算出用户距离Unix纪元有多少TX间隔。

让SecretKey=";digitalBunker";让Counter=";53283545";让hmacResult:String=SecretKey.hmac(算法:.SHA1,计数器:计数器)。

十六进制字符串现在等于31 4f 79 5a 52 6a 62 66 68 65 2b 38 77 6f 6d 6c 64 38 78 6c 64 58 6f 35 56 39 4d 3d。

这不是我们可以要求用户在每次需要身份验证时都键入的内容。让我们看看我们是否可以找到一种更简单的方式来表示这一点-6位代码将是一个很好的用户友好的替代方案。

我们将通过一个称为动态截断的过程将这个散列值转换为较短的代码。

动态截断涉及获取十六进制字符串最后一个字节的低4位,并将其用作字符串的偏移量,以帮助我们创建6位代码,同时仍然保持安全。

最后一个字节是3D,这意味着最后4位属于d(十进制13)的十六进制值。

31 4f 79 5a 52 6a 62 66 68 65 2b 38 77 6f 6d 6c 64 38 78 6c 64 58 6f 35 56 39 4d 3d。

这些位操作都是动态截断过程的一部分。我们正在进行所有这些操作,以找到一个仍然尽可能安全的6位代码。

现在,我们将0x6f6d6c64转换为十进制,得到1869442148。因为我们只需要6位代码,所以我们可以取最后6位442148并将其返回给用户。

现在,服务器将执行完全相同的步骤序列。更准确地说,它将检查当前的30秒间隔、前一个间隔和下一个间隔,以说明时钟漂移。如果服务器的代码与用户输入的代码匹配,则用户通过身份验证。

TOPT和HOPT都是备受推崇的算法,但值得一提的是其局限性。TOTP值可以像其他密码一样被网络钓鱼,但攻击者必须近乎实时地窃取凭据。

如果这是一个问题,您可以缩短代码的TTL。TOTP代码的标准TTL的范围从10到30秒不等,以考虑延迟(客户端和服务器端)、不同步的时钟以及用户可用性-您可以根据需要随意调整TTL。但是,如果攻击者能够找到共享密钥,他们就可以随意创建有效的TOTP代码。

希望您喜欢这篇详细介绍TOTP算法及其细微差别的文章!如果您喜欢这样的联系方式,请加入我们的邮件列表。如果有任何文章请求或评论,请随时联系。