谷歌身份验证器Google Authenticator是谷歌推出的一款动态口令工具,解决大家各平台账户遭到恶意攻击的问题,一般在相关的服务平台登陆中除了用正常用户名和密码外,需要再输入一次谷歌认证器生成的动态口令才能验证成功,相当于输入二次密码,以达到账户的高安全性。例如交易所、金融平台、以及一些钱包等项目等等,都会使用谷歌身份验证器Google Authenticator来做二次认证,开启谷歌身份验证之后,登录账户,除了输入用户名和密码,还需要输入谷歌验证器上的动态密码。谷歌验证器上的动态密码,也称为一次性密码,密码按照时间或使用次数不断动态变化(默认 30 秒变更一次)

  • 使用思路
    1、第一次请求,判断未绑定谷歌验证码,那就生成随机base32的秘钥展示到页面,供用户创建账号,或者生成二维码,供用户在手机端使用谷歌验证器扫码创建账号
    2、绑定验证,将手机app谷歌验证器生成的验证码输入到需要登录的平台验证,成功后将秘钥存入数据库;
    3、绑定过后每次请求查询数据库的秘钥生成二维码传出;
    4、取消绑定,清除数据库的数据。
  • 使用步骤
    手机上下载谷歌身份验证器,便于生成验证码
    iPhone手机:在App Store中搜索 Google Authenticator
    安卓手机:复制该链接到浏览器下载,http://d7.xiaotongqq.com/googe.apk
  • 整合java
    1.导入依赖
      <!--胡图工具包--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.2</version></dependency><!--二维码的生成工具类--><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.3.3</version></dependency><!--谷歌身份验证器--><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.12</version></dependency>

2.编写谷歌身份验证器工具类

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.Base64;/*** @Description: 谷歌身份验证器工具类*/
public class GoogleAuthenticator {/*** 生成秘钥的长度*/public static final int SECRET_SIZE = 10;public static final String SEED = "g8GjEvTbW5oVSV7avL47357438reyhreyuryetredLDVKs2m0QN7vxRs2im5MDaNCWGmcD2rvcZx";/*** 实现随机数算法*/public static final String RANDOM_NUMBER_ALGORITHM = "SHA1PRNG";/*** 时间前后偏移量* 用于防止客户端时间不精确导致生成的TOTP与服务器端的TOTP一直不一致* 如果为0,当前时间为 10:10:15* 则表明在 10:10:00-10:10:30 之间生成的TOTP 能校验通过* 如果为1,则表明在* 10:09:30-10:10:00* 10:10:00-10:10:30* 10:10:30-10:11:00 之间生成的TOTP 能校验通过* 以此类推*/int window_size = 10; // default 3 - max 17/*** set the windows size. This is an integer value representing the number of* 30 second windows we allow The bigger the window, the more tolerant of* clock skew we are.** @param s*            window size - must be >=1 and <=17. Other values are ignored*/public void setWindowSize(int s) {if (s >= 1 && s <= 17)window_size = s;}/*** 生成随机密钥,每个用户独享一份密钥* @return secret key*/public static String generateSecretKey() {SecureRandom sr = null;try {sr = SecureRandom.getInstance(RANDOM_NUMBER_ALGORITHM);sr.setSeed(Base64.decodeBase64(SEED.getBytes()));byte[] buffer = sr.generateSeed(SECRET_SIZE);Base32 codec = new Base32();byte[] bEncodedKey = codec.encode(buffer);return new String(bEncodedKey);} catch (NoSuchAlgorithmException e) {// should never occur... configuration error}return null;}/*** 生成一个google身份验证器,识别的字符串,只需要把该方法返回值生成二维码扫描就可以了。* 最后展示的账户名称将会是 label:user* @param label 标签* @param user 账号* @param secret 密钥* @return*/public static String getQRBarcode(String label, String user, String secret) {String format = "otpauth://totp/%s:%s?secret=%s";return String.format(format, label, user, secret);}/*** 生成一个google身份验证器,识别的字符串,只需要把该方法返回值生成二维码扫描就可以了。*最后展示的账户名称将会是 user* @param user 账号* @param secret 密钥* @return*/public static String getQRBarcode(String user, String secret) {String format = "otpauth://totp/%s?secret=%s";return String.format(format, user, secret);}/*** 验证code是否合法* @param secret 秘钥* @param code 验证码* @param timeMses 时间戳* @return true表示正确 false 表示错误*/public  boolean check_code(String secret, long code, long timeMses) {if(secret == null || "".equals(secret)){return false;}Base32 codec = new Base32();byte[] decodedKey = codec.decode(secret);// convert unix msec time into a 30 second "window"// this is per the TOTP spec (see the RFC for details)long t = (timeMses / 1000L) / 30L;// Window is used to check codes generated in the near past.// You can use this value to tune how far you're willing to go.for (int i = -window_size; i <= window_size; ++i) {long hash;try {hash = verify_code(decodedKey, t + i);} catch (Exception e) {// Yes, this is bad form - but// the exceptions thrown would be rare and a static// configuration probleme.printStackTrace();throw new RuntimeException(e.getMessage());// return false;}if (hash == code) {return true;}}// The validation code is invalid.return false;}/*** 根据时间偏移量计算** @param key* @param t* @return* @throws NoSuchAlgorithmException* @throws InvalidKeyException*/private static int verify_code(byte[] key, long t) throws NoSuchAlgorithmException, InvalidKeyException {byte[] data = new byte[8];long value = t;for (int i = 8; i-- > 0; value >>>= 8) {data[i] = (byte) value;}SecretKeySpec signKey = new SecretKeySpec(key, "HmacSHA1");Mac mac = Mac.getInstance("HmacSHA1");mac.init(signKey);byte[] hash = mac.doFinal(data);int offset = hash[20 - 1] & 0xF;// We're using a long because Java hasn't got unsigned int.long truncatedHash = 0;for (int i = 0; i < 4; ++i) {truncatedHash <<= 8;// We are dealing with signed bytes:// we just keep the first byte.truncatedHash |= (hash[offset + i] & 0xFF);}truncatedHash &= 0x7FFFFFFF;truncatedHash %= 1000000;return (int) truncatedHash;}
}

3.测试生成秘钥

import cn.hutool.core.io.FileUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import com.example.vehicleinformationsystem.util.GoogleAuthenticator;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class VehicleInformationSystemApplicationTests {private static String secretKey = "";/*** 生成秘钥*/@Testvoid contextLoads() {//生成秘钥secretKey = GoogleAuthenticator.generateSecretKey();System.out.println("秘钥:"+secretKey);}}

结果:

秘钥:DPSKD2HAZVANIXX7

秘钥使用方式:
注:该秘钥应该提示用户备份,切勿泄露给第三方,仅展示一次
3.1.在手机上下载谷歌身份验证器(下载方式参考上文)
3.2.点击右下角加号

3.3.点击输入设置秘钥
3.4.输入需要登录的平台用户名,以及刚才的秘钥,选择基于时间,点击添加

3.5.添加成功后,如下所示

3.6.将账号的二维码填写到需要登录的平台进行验证
4.测试生成二维码

    /*** 生成二维码*/@Testvoid contextLoads() {//生成秘钥secretKey = GoogleAuthenticator.generateSecretKey();System.out.println("秘钥:"+secretKey);//生成二维码信息String QRBarcode = GoogleAuthenticator.getQRBarcode("system_admin",secretKey);System.out.println("二维码所需要的信息:"+QRBarcode);//生成二维码  300 表示二维码的大小  D:\img\aa\qrcode.jpg 表示为二维码的生成路径QrCodeUtil.generate(QRBarcode, 300, 300, FileUtil.file("D:\\img\\aa\\qrcode.jpg"));}

生成结果:

使用方式:
4.1.在手机上下载谷歌身份验证器(下载方式参考上文)
4.2.点击右下角加号
4.3.点击扫描二维码
4.4.扫描生成的二维码,即可
5.5.将账号的二维码填写到需要登录的平台进行验证

5.验证码验证
这里就选择刚才生成的秘钥账户,system

 //刚才生成的秘钥private static String secretKey = "DPSKD2HAZVANIXX7";/*** 测试验证码*/@Testvoid testData() {String code = "126128";long time = System.currentTimeMillis ();GoogleAuthenticator g = new GoogleAuthenticator ();boolean result = g.check_code (secretKey,Long.valueOf(code),time );System.out.println ( "验证码是否正确--》"+result );}

输出结果:

验证码是否正确--》true

谷歌身份验证器的使用超详细步骤相关推荐

  1. 如何为SSH登录建立双因子验证机制(谷歌身份验证器)?

    前言 默认情况下,SSH已经在远程机器之间使用安全的数据通信;但是如果你想为自己的SSH连接添加另外某种安全层,可以添加谷歌身份验证器(Google Authenticator)双因子验证模块,该模块 ...

  2. 使用谷歌身份验证器增强SSH安全

    一般大家都是使用账号和密码远程SSH登录管理服务器.但SSH账号和密码很容易泄露,或者经常遭遇暴力破解.咨询过前同事赛赛,他们目前使用了谷歌身份验证器.查看了谷歌身份验证器的github和其它网上文档 ...

  3. 使用谷歌身份验证器(Google Authenticator)保护你的后台

    为何要使用谷歌身份验证器 普通的网站只使用账号.密码.图形验证码进行后台登录.根据我(作为站长)多年的经验来看,这种方式安全性很低,尤其是使用 http 协议,明文的帐号和密码相当于在网络上裸奔.如果 ...

  4. 谷歌身份验证器 手表_6条使您的三星手表更加Google-y的提示

    谷歌身份验证器 手表 Samsung 三星 Samsung Galaxy watches are, arguably, the best smartwatches for Android phones ...

  5. 使用C++实现谷歌身份验证器(Google Authenticator)

    使用C++实现谷歌身份验证器(Google Authenticator) 本机环境: windows10 x64位运行环境 1.进入网站:http://slproweb.com/products/Wi ...

  6. 二次验证码小程序与谷歌身份验证器不同点是?

    名称1[二次验证码]小程序 名称2 谷歌身份验证器(Google Authenticator) 粗略对比两个产品异同 [二次验证码]小程序 搜索:微信搜索.微信目前65个小程序入口,倒是容易找到它 使 ...

  7. Google Authenticator windows client 谷歌身份验证器 windows 电脑端

    谷歌身份验证器现在有安卓客户端和ios客户端,本人开发了一个windows客户端,基于 .NETFramework v4.7 开发,已在 github 上开源,可以在 github 上直接下载. gi ...

  8. 动态令牌 (谷歌身份验证器)的实现

    动态令牌-(OTP,HOTP,TOTP)-基本原理:  https://www.cnblogs.com/navysummer/p/11943319.html 实现原理: https://blog.cs ...

  9. 谷歌身份验证器代码实现

    手机下载谷歌身份验证器,无需联网也可以用. 工具类 public class GoogleAuthenticator{// 生成的key长度( Generate secret key length)p ...

  10. 为什么用户不敢用谷歌身份验证器?

    应用场景 在我们进行大额资金交易的时候,或者需要预防盗号等安全性强的操作时,会用到两步验证.这类两步验证一般有3种形式:手机短信验证(一般是注册手机).邮件验证(一般是绑定邮箱).第三方验证工具:验证 ...

最新文章

  1. 项目构建之maven篇:2.HelloWorld项目构建过程
  2. 不借助第三方工具查看映像路径(系统进程路径).
  3. SlidingMenu实现侧滑
  4. OpenCV演示代码以查找图像中的轮廓(附完整代码)
  5. linux c的连接库和怎么同时编译多个源程序
  6. 【ZOJ - 3715】Kindergarten Election(枚举得票数,贪心)
  7. java 异常练习题_Java 异常(习题)
  8. SQL Server单表查询语句
  9. Nginx的反向代理的配置
  10. select函数的并发限制和 poll 函数应用举例
  11. 你会几种“复制”文本的方式?----浅谈I/O流
  12. Speaker Recognition: GMM-UBM
  13. 莫言诺贝尔文学奖演讲全文:《讲故事的人》(推荐)
  14. Windows下测试算法在FDDB数据库的性能
  15. 现网必用的主备冗余技术,VRRP理论+配置
  16. 用Python做股市数据分析(二)
  17. 医疗项目业务以及表设计介绍
  18. 转:CWnd的函数,以后可以在这儿找了!
  19. 使用ASProfile分析可变剪切事件
  20. 基于android物流快递服务系统app

热门文章

  1. 交通分析小区TAZ生成——以武汉市为例
  2. localhost已拒绝连接
  3. [python]python的注释格式
  4. 城堡争霸显示服务器忙,城堡争霸 - 阵营守护神显示应用未安装怎么办
  5. 计算机图像处理顶级教授,【科研新成果】我院两项成果被图像处理领域顶级期刊录用...
  6. 2017计算机夏令营汇总
  7. 【周赛266】leetcode2062.统计字符串中的的元音子字符串
  8. win10专业版与家庭版区别分析
  9. 梁念坚:从MOTO到微软 从无缝连接到统一沟通
  10. 多维特征输入,多层神经网络学习