两步验证杀手锏:Java 接入 Google 身份验证器实战
两步验证
大家应该对两步验证都熟悉吧?如苹果有自带的两步验证策略,防止用户账号密码被盗而锁定手机进行敲诈,这种例子屡见不鲜,所以苹果都建议大家开启两步验证的。
Google 的身份验证器一般也是用于登录进行两步验证,和苹果的两步验证是同样的道理。只不过 Google 的身份验证器用得更多更广泛,如 GitHub 的两步验证都是基于 Google 身份验证器。
Google Authenticator 简介
Google Authenticator 身份验证器是一款基于时间与哈希的一次性密码算法的两步验证软件令牌,用户需要下载手机 APP(Authenticator),该手机 APP 与网站进行绑定,当网站验证完用户名和密码之后会验证此 APP 上对应生成的 6 位验证码数字,验证通过则成功登录,否则登录失败。
Google Authenticator 使用
我们来看下 Github 上的使用 Google 身份验证器开启两步验证的应用。
如图所示,默认 Github 是没有开启两步验证的,点击设置按钮进行设置。

Github 提供了基于 APP (谷歌身份验证器)和短信验证码两种两步验证的方式,我们选择第一种谷歌身份验证器。

进入第一种验证模式,接下来展示了一堆的恢复码,用来当 APP 验证器不能工作的紧急情况使用。把它们保存起来,然后点击下一步。

这个就是身份验证器的关键了,下载 Google 的 Authenticator APP,然后扫描这个二维码进行绑定。

绑定之后,APP Github 模块下面会显示一个 6 位的验证码,把它输入到上面那个框里面就行了。

如下图所示,已经成功开启两步验证了。

接下来我们退出 Github 再重新登录,页面就会提示要输入 Google 的身份验证器验证码了,如果 APP 不能正常工作,最下方还能通过之前保存下来的恢复码进行登录。

好了,Google Authenticator 使用就到这里,那它是如何工作的,它是什么原理呢?我们的网站、APP 如何接入 Google Authenticator,接下来我们一一拉开谜底。
Google Authenticator 工作流程
实际上 Google Authenticator 采用的是 TOTP 算法(Time-Based One-Time Password,即基于时间的一次性密码),其核心内容包括以下三点。
1、安全密钥
是客户端和服务端约定的安全密钥,也是手机端 APP 身份验证器绑定(手机端通过扫描或者手输安全密钥进行绑定)和验证码的验证都需要的一个唯一的安全密钥,该密钥由加密算法生成,并最后由 Base32 编码而成。
2、验证时间
Google 选择了 30 秒作为时间片,T的数值为 从Unix epoch(1970年1月1日 00:00:00)来经历的 30 秒的个数,所以在 Google Authenticator 中我们可以看见验证码每个 30 秒就会刷新一次。
更详细原理参考:
https://blog.seetee.me/post/2011/google-two-step-verification/
3、签署算法
Google 使用的是 HMAC-SHA1 算法,全称是:Hash-based message authentication code(哈希运算消息认证码),它是以一个密钥和一个消息为输入,生成一个消息摘要作为输出,这里以 SHA1 算法作为消息输入。
使用 HMAC 算法是因为只有用户本身知道正确的输入密钥,因此会得到唯一的输出,其算法可以简单表示为:
hmac = SHA1(secret + SHA1(secret + input))
事实上,TOTP 是 HMAC-OTP(基于HMAC的一次密码生成)的超集,区别是 TOTP 是以当前时间作为输入,而HMAC-OTP 则是以自增计算器作为输入,该计数器使用时需要进行同步。
Google Authenticator 实战
知道上面的原理,我们就可以来应用实战了。
/**
 * 微信公众号:Java技术栈
 */
public class AuthTest {
	@Test
	public void genSecretTest() {
		String secret = GoogleAuthenticator.generateSecretKey();
		String qrcode = GoogleAuthenticator.getQRBarcodeURL("Java技术栈", "javastack.cn", secret);
		System.out.println("二维码地址:" + qrcode);
		System.out.println("密钥:" + secret);
	}
	@Test
	public void verifyTest() {
		String secret = "ZJTAQGLVOZ7ATWH2";
		long code = 956235;
		GoogleAuthenticator ga = new GoogleAuthenticator();
		boolean r = ga.verifCode(secret, code);
		System.out.println("是否正确:" + r);
	}
}
第一个方法是生成密钥和一个扫描二维码绑定的URL。
第二个方法是根据密钥和验证码进行验证。
这里仅提供一下 GoogleAuthenticator 类的源码逻辑参考。
如果有收获欢迎点赞转发,也可以留言发表你的疑问和看法。
教程:史上最强 Spring Boot & Cloud 教程汇总
两步验证杀手锏:Java 接入 Google 身份验证器实战的更多相关文章
- Java使用google身份验证器实现动态口令验证
		
参考: 1)https://www.jb51.net/article/121243.htm 2)https://www.cnblogs.com/wuaili/p/9810661.html
 - 使用google身份验证器实现动态口令验证
		
最近有用户反应我们现有的短信+邮件验证,不安全及短信条数限制和邮件收验证码比较慢的问题,希望我们 也能做一个类似银行动态口令的验证方式.经过对可行性的分析及慎重考虑,可以实现一个这样的功能. 怎么实现 ...
 - 通过Google身份验证器加强Linux帐户安全
		
下载Google的身份验证模块: # wget https://google-authenticator.googlecode.com/files/libpam-google-authenticato ...
 - linux上使用google身份验证器(简版)
		
系统:centos6.6 下载google身份验证包google-authenticator-master(其实只是一个.zip文件,在windwos下解压,然后传进linux) #cd /data/ ...
 - centos7系统配置系统用户基于ssh的google身份验证
		
最近也是服务器各种被入侵,所以在安全上,要万分注意,特此记录,借助google的身份验证插件,获取动态验证码完成ssh登陆. OS: centos7 安装配置: 1. 安装epel源 yum -y i ...
 - 采用集成的Windows验证和使用Sql Server身份验证进行数据库的登录
		
采用集成的Windows验证和使用Sql Server身份验证进行数据库的登录 1.集成的Windows身份验证语法范例 1 string constr = "server=.;databa ...
 - google 身份验证器
		
谷歌身份验证器原理 就是服务器与客户端算法相同
 - [转载]SQL Server 2008 R2安装时选择的是windows身份验证,未选择混合身份验证的解决办法
		
安装过程中,SQL Server 数据库引擎设置为 Windows 身份验证模式或 SQL Server 和 Windows 身份验证模式.本文介绍如何在安装后更改安全模式. 如果在安装过程中选择&q ...
 - windows身份验证模式和SQL server身份验证模式 有什么不同
		
两个验证方式是有明显不同的. 主要集中在信任连接和非信任连接. windows 身份验证相对于混合模式更加安全,使用本连接模式时候,sql不判断sa密码,而仅根据用户的windows权限来进行身份验证 ...
 
随机推荐
- luogu P1064|| 01背包||金明的预算
			
题目描述如下 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过 NNN 元 ...
 - selenium+java定位163/126邮箱元素显示定位失败解决
			
开始在没有进入iframe时,用任何方法定位163/126邮箱登录页面的元素都不可能定位到,eclipse工作台会显示Unable to locate element:…… 这种情况我遇到了两种原因: ...
 - 利用idea解决git代码冲突问题
			
问题描述:在开发过程中,如果你开发的代码与其他人造成冲突,在不处理的情况下会无法拉取,并且提交容易造成代码丢失: 解决方法: [此方法是同事郭富城的分享] 1,由于冲突,我们每次拉取都会失败,这时我们 ...
 - 获取Vue的实例方法
			
我们知道在new Vue({...})后,如果没有赋值给一个变量存储,我们很难拿到这个实例,Vue官方也没有提供Vue.getInstance方法,那我们就自己扩展个吧 Code: Vue.getIn ...
 - 对Python选修课的期望
			
作为一个之前完全没有接触过任何计算机语言的人我对于Python完完全全是个小白,那么我就以一个菜鸟的角度来谈谈我对这门选修课的期望吧. ...
 - 【MySQL】初识数据库及简单操作
			
一.数据库概述 1.1 什么是数据(Data) 描述事物的符号记录称为数据,描述事物的符号既可以是数字,也可以是文字.图片,图像.声音.语言等,数据由多种表现形式,它们都可以经过数字化后存入计算机. ...
 - java中产生HttpServletRequest等作用域
			
protected ServletContext getServletContext() { return ServletActionContext.getServletContext();} pro ...
 - 关于tomcat7配置maxPostSize=“0”时,后台无法接收前台参数的问题
			
Post提交参数时,如果参数值的长度太长,后台通过Map<String, String[]> requestParameterMap=request.getParameterMap();获 ...
 - asp:DropDownList 使用
			
<asp:DropDownList ID="DropDownList1" runat="server" onchange="return My_ ...
 - linux系统下部署DNS反向解析
			
DNS服务概述 DNS(Domain Name System)域名系统,能够提供域名与IP地址的解析服务. 反向解析 反向解析是从IP地址到域名的解析过程.主要作用于服务器的身份验证. 部署反向解析 ...