<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>两步验证 on 浅忆博客</title>
    <link>https://blog.curlc.com/tags/%E4%B8%A4%E6%AD%A5%E9%AA%8C%E8%AF%81/</link>
    <description>Recent content in 两步验证 on 浅忆博客</description>
    <image>
      <title>浅忆博客</title>
      <url>https://blog.curlc.com/images/papermod-cover.png</url>
      <link>https://blog.curlc.com/images/papermod-cover.png</link>
    </image>
    <generator>Hugo</generator>
    <language>zh</language>
    <copyright>黔ICP备15002488号</copyright>
    <lastBuildDate>Fri, 06 Jul 2018 06:28:03 +0000</lastBuildDate>
    <atom:link href="https://blog.curlc.com/tags/%E4%B8%A4%E6%AD%A5%E9%AA%8C%E8%AF%81/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>基于时间的一次性密码 TOTP</title>
      <link>https://blog.curlc.com/archives/120/</link>
      <pubDate>Fri, 06 Jul 2018 06:28:03 +0000</pubDate>
      <guid>https://blog.curlc.com/archives/120/</guid>
      <description>&lt;p&gt;TOTP 是一个基于时间的一次性密码算法（也称时间同步的动态密码）。它使用共享密钥和当前时间来生成一个密码，目前这个算法已经写入国际标准 RFC 6238，并且多被用于双因素认证（2FA）系统。&lt;/p&gt;
&lt;h2 id=&#34;算法原理&#34;&gt;算法原理&lt;/h2&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://www.vtrois.com/wp-content/uploads/totp.png&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;简介&#34;&gt;简介&lt;/h3&gt;
&lt;p&gt;动态口令的基本认证原理是认证双方使用同一个共享密钥对时间进行密码算法计算，之后比较计算值是否一致从而进行认证。TOTP 使用加密散列函数将密钥与当前时间戳结合，来生成一次性密码。 在认证双方比对计算值是否一致的过程中会有各种原因的延迟。比如在同一个哈希有效期的时间长度内，动态密码生成的结果是一样的，但是由于网络的原因，客户端生成密码的时间和服务器接受密码的时间可能差距会很大，导致两个密码不在同一个哈希有效期的时间长度内，所以导致认证失败。这个时候就需要验证系统有一个延时的策略，可以允许验证前几个哈希有效期的时间长度的动态密码。但是哈希有效期的时间长度设置的越大，就会更容易导致被攻击破解，并且每一个哈希有效期的时间长度只会生成一个密码，所以时间如果过长的话会影响用户体验，因此权衡考虑安全性和可用性这里默认的哈希有效期的时间长度为 30 秒。&lt;/p&gt;
&lt;h3 id=&#34;算法&#34;&gt;算法&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;TOTP&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;Truncate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;HMAC&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;−&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SHA&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;−&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SecretKey&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,((&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;unixtime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;−&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;unixtime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;TS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;HMAC−SHA−1&lt;/code&gt; 是从 SHA1 哈希函数构造的一种哈希算法，被用作 HMAC（基于哈希的消息验证代码），此 HMAC 进程将密钥与消息数据混合，使用哈希函数对混合结果进行哈希计算，将所得哈希值与该密钥混合，然后再次应用哈希函数，输出的哈希值长度为 160 位。&lt;code&gt;SecretKey&lt;/code&gt; 是服务端与客户端共享的一个任意字节的秘钥。&lt;code&gt;unixtime(now)&lt;/code&gt; 是当前 &lt;code&gt;Unix&lt;/code&gt; 时间戳，&lt;code&gt;unixtime(T0)&lt;/code&gt; 是约定的起始时间点的时间戳，默认是 0 ，也就是 1970年1月1日。 &lt;code&gt;TS&lt;/code&gt; 为哈希有效期的时间长度，默认为 30 秒。&lt;/p&gt;
&lt;h3 id=&#34;要求&#34;&gt;要求&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;服务端与客户端之间共享密钥&lt;/li&gt;
&lt;li&gt;服务端与客户端之间时间相同&lt;/li&gt;
&lt;li&gt;服务端与客户端之间使用相同的哈希有效期的时间长度&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;经典场景&#34;&gt;经典场景&lt;/h2&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://www.vtrois.com/wp-content/uploads/totp-tutorial.png&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;参考资料&#34;&gt;参考资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://tools.ietf.org/html/rfc6238&#34;&gt;RFC 6238 - Time-Based One-Time Password Algorithm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Cryptographic_hash_function&#34;&gt;Cryptographic hash function&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Hash-based_message_authentication_code&#34;&gt;Hash-based message authentication code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm&#34;&gt;Time-Based One-Time Password Algorithm&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;本文转自: https://www.vtrois.com/totp-tutorial.html&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
