网工干货知识

超全学习笔记
当前位置:首页 > 干货知识

密码学中的一次性密码生成算法

更新时间:2026年03月27日   作者:spoto   标签(Tag):

身份验证在授予任何受保护的服务(例如个人账户)的访问权限之前,识别并验证该用户身份是必不可少的基础步骤。 身份验证功能已纳入网络安全标准中,能够有效防止未经授权的人员访问受保护的资源。 目前,身份验证机制在解锁任何受保护的信息之前,都会先创建一个双层网关。 这种双层安全机制被称为“双因素认证”。它要求先验证用户的凭证(用户名/电子邮件和密码),然后再创建并验证相应的认证信息。一次性密码OTP是一种数字代码,它在每次认证过程中都会随机且唯一地生成。这种方式增加了额外的安全层,因为每次尝试认证时生成的密码都是全新的数字组合。此外,由于OTP具有不可预测的特性,因此能够为下一次会话提供更高的安全性。传递OTP的两种主要方式如下:

  1. 基于短信的通信方式:这其实很简单。在常规认证成功后,通过短信发送一次性密码是一种标准的操作方式。在这种情况下,一次性密码是在服务器端生成的,然后通过短信发送给认证人员。这种方式是各种服务中最为常见的发送一次性密码的方式。
  2. 基于应用程序的:这种OTP生成方式是在用户端通过特定的智能手机应用程序来完成的。该应用程序会扫描屏幕上的二维码,从而生成唯一的OTP数字。与基于短信的发送方式相比,这种方式能够减少等待时间,同时也能降低安全风险。

根据开放认证倡议所定义的OTP生成的常见方式就是……基于时间的一次性密码(TOTP)这是一种时间同步的OTP技术。在这种OTP系统中,时间是最重要的因素,因为它决定了唯一密码的生成方式。生成的密码是根据当前时间来确定的,同时还会考虑到一个秘密密钥。这种OTP生成方式的例子就是所谓的“基于时间的OTP算法”(TOTP)。

  1. 后端服务器负责生成该秘密密钥。
  2. 该服务器会将秘密密钥共享给负责生成一次性密码的服务。
  3. 基于哈希值的消息认证码(HMAC)是通过使用获得的密钥和当前时间来生成的。 这是通过加密的SHA-1算法来实现的。 由于负责发送OTP的服务器以及请求OTP的设备都拥有对时间的访问权限,而时间本身显然是动态变化的。因此,时间被作为算法中的一个参数来使用。 在这里,使用的是与时区无关的Unix时间戳。 时间以秒为单位进行计算,起始时间为1970年1月1日。 让我们把“0215a7d8c15b492e21116482b6d34fc4e1a9f6ba”视为由HMAC-SHA1算法生成的字符串。
  4. 生成的代码长度为20字节,因此会被截断为适合用户输入的适当长度。这里采用了动态截断的方式。对于长度为20字节的代码“0215a7d8c15b492e21116482b6d34fc4e1a9f6ba”,每个字符占用4位。因此,整个字符串被视作由20个独立的一字节字符串组成。我们来看最后一个字符,这里是“a”。 其十进制数值被用来确定开始进行截断的偏移量。 从偏移值10开始,再读取接下来的31位,就可以得到字符串“6482b6d3”。 最后需要做的事情就是,将我们得到的十六进制数值转换为十进制数值。经过转换之后,我们得到的结果是1686288083。 现在,我们所需要的,就是得到的小数字符串中最后几位OTP数字的长度。如果有必要的话,还可以用零来填充这些空缺的位置。 这可以通过对十进制字符串进行取模运算来实现,具体操作是:将十进制字符串除以 10 的所需位数次方,然后再取余数。这样就能得到所需的OTP了。 最终,我们得到的TOTP代码是“288083”。
  5. 计数器用于记录经过的时间,并在设定的时间间隔后生成新的代码。
  6. 上述方法生成的OTP会被以上述方式传递给用户。

除了上述基于时间的生成方法之外,还存在一些用于生成OTP的数学算法。例如,有一种单向函数,它可以根据之前生成的OTP来生成新的OTP。 双因素认证系统是一种有效的策略,它利用了“你知道的东西”和“你拥有的东西”这两种认证原则。其中,后一种认证原则的动态特性非常重要,而一次性密码算法正是实现了这一特性的有效手段。这种机制为系统提供了有效的保护,能够有效抵御恶意攻击者的攻击。 OTP的不可预测性,使得这种加密方式所具备的优势难以充分发挥出来。

示例:

我们将使用 Python 内置的模块来创建一个简单的一次性密码生成算法。秘密/机密该模块会生成一种一次性随机密码。这个密码将被用作用户的身份验证凭证。

说明:OTP算法会使用一个秘密密钥(即一段随机字符串)来生成一次性密码。这个“秘密密钥”必须妥善保管,不得与他人共享。秘密该模块提供了一个强大的随机性来源,可以用来安全地生成密钥。

我们将使用“”。secrets_token_hex()用于生成随机的密钥。secrets.choice()’该函数通过从预定义的字符集中随机选取字符来生成随机的OTP。

让我们来看看这段代码以及其输出结果吧:

Java
// 用于演示OTP算法的Java程序进口java.security.SecureRandom;// 驱动类类别/等级 GFG{// 用于生成随机秘密密钥的函数公共的静态的字符串生成随机密钥(){SecureRandomsecureRandom=新的SecureRandom();字节[]字节=新的字节[16];secureRandom.下一个字节(字节);StringBuildersecretKey=新的StringBuilder();为了(字节b:字节){secretKey.附加(字符串.格式(“%02x”,b));}返回secretKey.转换为字符串();}// 用于生成一次性密码的函数// 秘密密钥公开的静态的字符串生成一次性密码(字符串secretKey,整数长度){字符串允许使用的字符数=0123456789;StringBuilderOTP=新的StringBuilder();SecureRandomsecureRandom=新的SecureRandom();为了(整数i=0;i<长度;i++){整数随机索引=secureRandom.下一个整数(允许使用的字符数.长度());OTP.添加/附加(允许使用的字符数.charAt(随机索引));}返回OTP.转换为字符串();}公开的静态的无效/无意义主要/核心(字符串[]参数/变量){// 生成一个随机的秘密密钥// (这部分内容应该被妥善保护起来)字符串secretKey=生成秘密密钥();// 模拟将OTP发送给用户整数OTP长度=6;字符串OTP=生成一次性密码(secretKey,OTP长度);// 模拟用户输入以进行OTP验证Java.实用/有用.扫描仪扫描仪=新的Java.实用/有用.扫描仪(系统/体系.in);系统/体系.外出/离开.打印(请输入接收到的一次性验证码:);字符串用户输入=扫描仪.接下来();// 验证用户输入的OTP是否正确if(用户输入.等于(OTP)){系统/体系.出去.println(OTP验证成功。访问权限已授予!);}否则{系统/体系.外出/离开.println(OTP验证失败。访问被拒绝!);}}}
Python
进口 秘密# 用于生成随机秘密密钥的函数def 生成秘密密钥():    返回 秘密.令牌_十六进制(16)  # 16个字节(32个十六进制字符)# 用于使用密钥生成一次性密码的功能def 生成OTP(secret_key, 长度=6):    # 定义允许在一次性密码中使用的字符    允许使用的字符 = 0123456789    # 使用密钥和允许的字符来生成随机的OTP    OTP = ''.加入(秘密.选择(允许使用的字符) 为了 _ in 范围/幅度(长度))        返回 OTP# 使用示例if __name__ == __main__:    # 生成一个随机的秘密密钥(该密钥需要被妥善保存)    secret_key = 生成秘密密钥()    # 模拟将OTP发送给用户    OTP = 生成OTP(secret_key)    # 模拟用户输入以进行OTP验证    用户输入 = 输入(请输入接收到的一次性密码:)    # 请确认用户输入的验证码是否正确。    if 用户输入 == OTP:        打印(OTP验证成功。访问权限已授予!)    否则:        打印(OTP验证失败。访问被拒绝!)

输出结果:

请输入接收到的一次性密码:123456
OTP验证成功。访问权限已授予!

上述代码的说明:

  1. “那个”generate_secret_key()函数该函数能够生成一个长度为16字节的随机密钥,即32个十六进制字符。secrets_token_hex()如果需要的话,可以调整长度。不过,16字节被认为是足够安全的了。
  2. “The”generate_otp()函数该函数需要传入一个秘密密钥,以及一个可选的参数。长度“Argument”(默认值为6),用于指定一次性密码的长度。该参数会从字符串“0123456789”中随机选择字符来生成一次性密码,然后返回生成的密码。
  3. 在示例用法中,我们使用“”来生成一个随机的秘密密钥。generate_secret_key()函数这个密钥应该被妥善保管,不得与他人分享。
  4. 我们通过调用相关函数来模拟将一次性密码发送给用户的过程。生成OTP(密钥)并将OTP存储在变量“”中。OTP.
  5. 请用户输入接收到的一次性密码,并将其存储在变量“”中。用户输入.
  6. 最后,我们将用户输入的OTP与生成的OTP进行比对。如果两者匹配,则允许用户访问;否则,将拒绝其访问请求。
              马上抢免费试听资格
意向课程:*必选
姓名:*必填
联系方式:*必填
QQ:
思博SPOTO在线咨询

相关资讯

即刻预约

免费试听-咨询课程-获取免费资料