OTP动态口令之Java实现双重认证
Posted 花伤情犹在
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OTP动态口令之Java实现双重认证相关的知识,希望对你有一定的参考价值。
前言
双重认证(英语:Two-factor authentication,缩写为2FA),又译为双重验证、双因素认证、二元认证,又称两步骤验证(2-Step Verification,又译两步验证),是一种认证方法。
原理
动态密码的产生方式,主要是以时间差做为服务器与密代码生成器的同步条件。在需要登录的时候,就利用密代码生成器产生动态密码,OTP一般分为计次使用以及计时使用两种,计次使用的OTP产出后,可在不限时间内使用;计时使用的OTP则可设置密码有效时间,从30秒到两分钟不等,而OTP在进行认证之后即废弃不用,下次认证必须使用新的密码,增加了试图不经授权访问有限制资源的难度。
TOTP技术标准
https://datatracker.ietf.org/doc/html/rfc6238
相关技术文档
OTP扫描用字符串格式
格式:
otpauth://totp/账号?secret=秘钥
示例:
otpauth://totp/花伤情犹在?secret=RR7VFLUFFJPJ4FYFS66REZG6FROEI55M
可以手动输入账户和秘钥添加令牌
使用阿里云身份宝
或者Google Authenticator
时间同步实现OTP动态口令
或者将OTP字符串生成二维码
草料二维码生成器:https://cli.im/
手动输入账户和秘钥 或者 扫描二维码 即可添加令牌
利用Google API生成二维码
此项目就是利用Google API
生成的二维码
链接参数详解:
https://chart.googleapis.com/chart?
这是Google Chart API的头部,直接照抄就好了~&cht=qr
这是说图表类型为qr也就是二维码。&chs=200×200
这是说生成图片尺寸为200×200,是宽x高。这并不是生成图片的真实尺寸,应该是最大尺寸吧。&choe=UTF-8
这是说内容的编码格式为UTF-8,此值默认为UTF-8.其他的编码格式请参考Google API文档。&chld=L|4 L
代表默认纠错水平; 4代表二维码边界空白大小,可自行调节。具体参数请参考Google API文档。&chl=XXXX
这是QR内容,也就是解码后看到的信息。包含中文时请使用UTF-8编码汉字,否则将出现问题。
j256开源两步验证
两步验证
<dependency>
<groupId>com.j256.two-factor-auth</groupId>
<artifactId>two-factor-auth</artifactId>
<version>1.3</version>
</dependency>
两步验证Java代码
两步身份验证 (2FA) Java 代码,它使用基于时间的一次性密码 (TOTP) 算法。您可以将此代码与 Google Authenticator 移动应用程序或 Authy 移动或浏览器应用程序一起使用。
- 请参阅有关 TOTP 的维基百科页面
- 可从git 存储库获取代码
- Maven 包通过以下方式发布
生成秘钥
- 用于generateBase32Secret()为用户生成 base-32 格式的密钥。例如:“NY4A5CPJZ46LXZCP”
- 将密钥存储在与用户帐户关联的数据库中。
- 显示返回qrImageUrl(…)给用户的二维码图片URL。
用户使用图像将密钥加载到他的身份验证器应用程序中。
验证秘钥
- 用户将来自验证器应用程序的号码输入到 Web 服务器上的登录表单中。
- Web 服务器从数据库中读取与用户帐户关联的密钥。
- 服务器将用户输入与来自 的输出进行比较generateCurrentNumberString(…)。
- 如果它们相等,则允许用户登录。
代码示例
public static void main(String[] args) throws Exception
// 生成Base32秘钥
String base32Secret = TimeBasedOneTimePasswordUtil.generateBase32Secret(32);
System.out.println("secret = " + base32Secret);
// 这是可以由验证程序显示的密钥的名称
String keyId = "hsqyz";
// 生成二维码
System.out.println("Image url = " + TimeBasedOneTimePasswordUtil.qrImageUrl(keyId, base32Secret));
//我们可以将此图像显示给用户,让他们将其加载到他们的身份验证程序中
// 我们可以在这里使用代码并将其与用户输入进行比较
String code = TimeBasedOneTimePasswordUtil.generateCurrentNumberString(base32Secret);
System.out.println("code : "+code);
/*
* 此循环显示数字如何随时间变化
*/
while (true)
long diff = TimeBasedOneTimePasswordUtil.DEFAULT_TIME_STEP_SECONDS
- ((System.currentTimeMillis() / 1000) % TimeBasedOneTimePasswordUtil.DEFAULT_TIME_STEP_SECONDS);
code = TimeBasedOneTimePasswordUtil.generateCurrentNumberString(base32Secret);
System.out.println("Secret code = " + code + ", change in " + diff + " seconds");
Thread.sleep(1000);
suyin58开源两步验证
数据库表结构:
CREATE TABLE `t_user` (
`username` varchar(30) COLLATE utf8_bin NOT NULL,
`otp_sk` varchar(64) COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
创建用户
- 运行RegistTest的main方法,注意修改f_temp[临时二维码图片存放目录],email[接收二维码图片邮箱地址]
工程部署在tomcat下,登录地址 - http://127.0.0.1:8580/login.jsp
以上是关于OTP动态口令之Java实现双重认证的主要内容,如果未能解决你的问题,请参考以下文章