pom文件

        <dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.10</version></dependency><!-- Google Zxing 二维码 --><dependency><groupId>com.google.zxing</groupId><artifactId>javase</artifactId><version>3.3.0</version></dependency>

GoogleGenerator

package com.xiaoq.galaxy.util;import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.Base64;import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;public class GoogleGenerator {// 生成的key长度( Generate secret key length)public static final int SECRET_SIZE = 10;public static final String SEED = "22150146801713967E8g";// Java实现随机数算法public static final String RANDOM_NUMBER_ALGORITHM = "SHA1PRNG";// 最多可偏移的时间int window_size = 3; // default 3 - max 17public static String generateSecretKey() {SecureRandom sr;try {sr = SecureRandom.getInstance(RANDOM_NUMBER_ALGORITHM);sr.setSeed(Base64.decodeBase64(SEED));byte[] buffer = sr.generateSeed(SECRET_SIZE);Base32 codec = new Base32();byte[] bEncodedKey = codec.encode(buffer);return new String(bEncodedKey);} catch (NoSuchAlgorithmException e) {e.printStackTrace();}return null;}/*** 这个format不可以修改,身份验证器无法识别二维码*/public static String getQRBarcode(String user, String secret) {String format = "otpauth://totp/%s?secret=%s";return String.format(format, user, secret);}/*** 根据user和secret生成二维码的密钥*/public static String getQRBarcodeURL(String user, String host, String secret) {String format = "http://www.google.com/chart?chs=200x200&chld=M%%7C0&cht=qr&chl=otpauth://totp/%s@%s?secret=%s";return String.format(format, user, host, secret);}public boolean check_code(String secret, String code, long timeMsec) {Base32 codec = new Base32();byte[] decodedKey = codec.decode(secret);long t = (timeMsec / 1000L) / 30L;for (int i = -window_size; i <= window_size; ++i) {long hash;try {hash = verify_code(decodedKey, t + i);} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e.getMessage());}System.out.println("code=" + code);System.out.println("hash=" + hash);if (code.equals(addZero(hash))) {return true;}}return false;}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;long truncatedHash = 0;for (int i = 0; i < 4; ++i) {truncatedHash <<= 8;truncatedHash |= (hash[offset + i] & 0xFF);}truncatedHash &= 0x7FFFFFFF;truncatedHash %= 1000000;return (int) truncatedHash;}private String addZero(long code) {return String.format("%06d", code);}
}

QRCodeUtil

package com.xiaoq.galaxy.util;import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;import java.util.HashMap;
import java.util.Map;/*** 二维码工具类*/
public class QRCodeUtil {/*** 生成二维码** @param content 二维码的内容* @return BitMatrix对象*/public static BitMatrix createCode(String content) {//二维码的宽高int width = 200;int height = 200;//其他参数,如字符集编码Map<EncodeHintType, Object> hints = new HashMap<>();hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");//容错级别为Hhints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);//白边的宽度,可取0~4hints.put(EncodeHintType.MARGIN, 0);BitMatrix bitMatrix = null;try {//生成矩阵,因为我的业务场景传来的是编码之后的URL,所以先解码bitMatrix = new MultiFormatWriter().encode(content,BarcodeFormat.QR_CODE, width, height, hints);//bitMatrix = deleteWhite(bitMatrix);} catch (WriterException e) {e.printStackTrace();}return bitMatrix;}/*** 删除生成的二维码周围的白边,根据审美决定是否删除** @param matrix BitMatrix对象* @return BitMatrix对象*/private static BitMatrix deleteWhite(BitMatrix matrix) {int[] rec = matrix.getEnclosingRectangle();int resWidth = rec[2] + 1;int resHeight = rec[3] + 1;BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);resMatrix.clear();for (int i = 0; i < resWidth; i++) {for (int j = 0; j < resHeight; j++) {if (matrix.get(i + rec[0], j + rec[1]))resMatrix.set(i, j);}}return resMatrix;}
}
package com.qhzx.common.utils;import com.qhzx.common.dto.CodeEnum;
import lombok.AllArgsConstructor;
import lombok.Data;import java.io.Serializable;@Data
@AllArgsConstructor
public class Result<T> implements Serializable {/****/private static final long serialVersionUID = -4696008537295855861L;
//  private T data;
//    private Integer code;
//    private String message;/*** 响应详情数据*/private T data;private Integer code;/*** 响应详情说明*/private String message;/*** 200响应结果*/public static final String SUCCESS = "success";/*** 失败响应结果*/public static final String FAIL = "fail";/*** 响应错误代码*/public static final int ERROR_CORD = 500;/*** 默认构造器*/public Result() {this.setCode(200);}/*** 状态码构造器*/public Result(int responseCode) {setCode(responseCode);this.setMessage("null");this.setData(null);}/*** 状态码 + 消息详情构造器*/public Result(Integer responseCode, String message) {this.setCode(responseCode);this.setMessage(message);this.setData(null);}public Result(Integer code) {}public T getData() {return data;}public void setData(T data) {this.data = data;}public void setCode(Integer code) {this.code = code;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public static <T> Result<T> succeed(T data) {return succeedWith(data, CodeEnum.SUCCESS.getCode(), "success");}public static <T> Result<T> succeed(T model, String msg) {return succeedWith(model, CodeEnum.SUCCESS.getCode(), msg);}public static <T> Result<T> succeedWith(T data, Integer code, String message) {return new Result<T>(data, code, message);}public static <T> Result<T> failed(String msg) {return failedWith(null, CodeEnum.ERROR.getCode(), msg);}public static <T> Result<T> failed(Integer code, String msg) {return failedWith(null, code, msg);}public static <T> Result<T> failed(T model, String msg) {return failedWith(model, CodeEnum.ERROR.getCode(), msg);}public static <T> Result<T> failedWith(T datas, Integer code, String msg) {return new Result<T>(datas, code, msg);}public static <T> Result<T> failed(Integer code, T result) {Result<T> jsonResult = new Result<T>(code);jsonResult.setData(result);jsonResult.setMessage(result + "");return jsonResult;}public static <T> Result<T> initSuccessResult(T result) {Result<T> jsonResult = new Result<T>(200);if (null != result) {jsonResult.setData(result);jsonResult.setMessage(Result.SUCCESS);}return jsonResult;}/*** 状态码 + 消息详情构造器*/public Result(int responseCode, String message) {this.setCode(responseCode);this.setMessage(message);this.setData(null);}
}

GoogleAuthController

package com.xiaoq.galaxy.controller;import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.xiaoq.galaxy.util.GoogleGenerator;
import com.xiaoq.galaxy.util.OperLog;
import com.xiaoq.galaxy.util.QRCodeUtil;
import com.xiaoq.galaxy.util.Result;
import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;@CrossOrigin
@RestController
@RequestMapping(value = "/googleAuth")
public class GoogleAuthController {//根据user和secret生成二维码的密钥@PostMapping(value = "/getQRBarcodeURL")@OperLog(operModul = "后台系统-getQRBarcodeURL",operDesc = "getQRBarcodeURL")public Result<String> getQRBarcodeURL(String user, String host, String secret) {return Result.succeed(GoogleGenerator.getQRBarcodeURL(user, host, secret));}//查看google 二维码信息@PostMapping(value = "/getQRBarcode")@OperLog(operModul = "后台系统-getQRBarcode",operDesc = "getQRBarcode")public Result<String> getQRBarcode(String user, String secret) {return Result.succeed(GoogleGenerator.getQRBarcode(user, secret));}/*** 生成二维码*/@GetMapping(value = "/generateQRCode")@OperLog(operModul = "后台系统-生成二维码",operDesc = "生成二维码")public void GenerateQRCode(String content, HttpServletResponse response) throws IOException {// 设置响应流信息response.setContentType("image/jpg");response.setHeader("Pragma", "no-cache");response.setHeader("Cache-Control", "no-cache");response.setDateHeader("Expires", 0);OutputStream stream = response.getOutputStream();//获取一个二维码图片BitMatrix bitMatrix = QRCodeUtil.createCode(content);//以流的形式输出到前端MatrixToImageWriter.writeToStream(bitMatrix, "jpg", stream);}//新增用户的时候生成密钥并且保存@GetMapping(value = "/geSecretKey")@OperLog(operModul = "后台系统-geSecretKey",operDesc = "geSecretKey")public Result<String> geSecretKey() {return Result.succeed(GoogleGenerator.generateSecretKey());}//验证code是否合法@PostMapping(value = "/checkValidCode")@OperLog(operModul = "后台系统-checkValidCode",operDesc = "checkValidCode")public Result<Boolean> checkGoogleValidCode(String secret, String code) {return Result.succeed(new GoogleGenerator().check_code(secret, code, System.currentTimeMillis()));}
}

Java实现谷歌验证器相关推荐

  1. 计算机器怎么验证,谷歌验证器【设置步骤】

    喜欢使用电脑的小伙伴们一般都会遇到win7系统谷歌验证器的问题,突然遇到win7系统谷歌验证器的问题就不知道该怎么办了,其实win7系统谷歌验证器的解决方法非常简单,按照 1:首先打开手机上的应用商店 ...

  2. laravel-admin加谷歌验证器

    示意图 添加谷歌验证首先需要 参考: Laravel-admin 登录添加图形验证码 构建一个自己的登录系统 安装扩展 composer require "earnp/laravel-goo ...

  3. PHP设置谷歌验证器(Google Authenticator)实现操作二步验证

    使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码.实现Google Authenticator功能需要服务 ...

  4. google authenticator python_谷歌验证器 Google Authenticator工作原理

    很多人都听过谷歌验证 (Google Authenticator) 或用过谷歌验证 (Google Authenticator) .尤其是随着比特币等虚拟货币的兴起,各大交易所都要求绑定谷歌验证 (G ...

  5. PHP实现谷歌验证器二次验证

    一.什么是谷歌身份验证器? 不少网站在登陆或者操作时都需要谷歌身份验证器(Google Authenticator),就是说在输入用户名和密码之后还需要输入一个动态密码,而这个动态密码由手机APP谷歌 ...

  6. linux安装谷歌验证器

    linux安装谷歌验证器 同步时间 下载程序并编译 设置pam.d/sshd 设置/etc/ssh/sshd_conf 重启sshd 登陆验证 同步时钟 root@li'bin:# service n ...

  7. 谷歌验证器的原理及JS实现

    阅读本篇文章你可以了解到谷歌验证器的实现原理,并且可以自己使用node.js实现支持谷歌验证器的两步验证. 这两年发现身边的很多应用和网站纷纷支持两步验证,并且呼吁用户使用两步验证. 并且发现,除了A ...

  8. DMCH支持谷歌验证器上链!

    首先介绍一下谷歌验证器(不是一般的强) 谷歌验证器是一种双因素身份安全认证器,具有双重安全保章,这个是一个移动终端的app应用,也可以布置到网站上进行安全布控,安全级别不是一般的高,类似国内支付宝所用 ...

  9. google authenticator python_谷歌验证器(Google Authenticator)

    双因素身份认证就是经过你所知道再加上你所能拥有的这二个要素组合到一块儿才能发挥做用的身份认证系统.双因素认证是一种采用时间同步技术的系统,采用了基于时间.事件和密钥三变量而产生的一次性密码来代替传统的 ...

最新文章

  1. 第十三届光华工程科技奖公布,彭士禄、张伯礼、王海峰等40人及1个团体获奖
  2. 没有java home_【Java安装】必须有JAVA_HOME变量吗
  3. sql server 中获取前一天日期_图解SQL面试题:如何比较日期数据?
  4. 用于WWW传输控制的是HTML,控制传输
  5. GDCM:gdcm::Validate的测试程序
  6. python判断数字_python判断变量是否为数字、字符串、列表、字典等
  7. hadoop:could only be replicated to 0 nodes, instead of 1
  8. java 内置函数_java8 四大内置核心函数式接口
  9. offsetParent
  10. kotlin 反射java类_Android Kotlin的Class、反射、泛型
  11. uricode(GET参数) 转 object
  12. pageHelper 分页插件使用
  13. 【Axure原型分享】会议管理原型模板
  14. 网站百度竞价有展现,点击无咨询原因
  15. 团队想招人,如何说服公司?写一封这样的人员招聘申请邮件,再看效果!
  16. idea+phpstudy完成php对数据库的操作
  17. OpenVZ平台魔改BBR之Rinetd
  18. diameter协议栈_Diameter协议摘要
  19. Chrome 神器面世!谷歌学术搜文章,代码链接自动展示
  20. Postman|网页调试工具

热门文章

  1. 基于 Java Spring Security 的关注微信公众号即登录的设计与实现 ya
  2. 计算机显卡调研,75%以上的人都想换显卡! MC调研报告告诉你吃鸡“帧”香
  3. 《MacTalk 跨越边界》一一1.2 人生如摆摊
  4. 怎么进入 BAT 的研发部门?
  5. 使用wait函数获取子进程终止状态
  6. 计算机视觉笔记及资料整理(含图像分割、目标检测小方向学习)
  7. 域用户指定计算机,什么是AD域,如何设置AD域用户仅登录到指定的计算机
  8. 最新51CTO学院vue.js项目实战课程
  9. [Go实战]简单使用scylladb
  10. 大学英语(第三册)复习(原文及全文翻译)——Unit 7 - The Shelter(防空洞)