实现一个Google身份验证代替短信验证
最近才知道公司还在做国外的业务,要实现一个登陆辅助验证系统。咱们国内是用手机短信做验证,当然 这个google身份验证只是一个辅助验证登陆方式。看一下演示


看到了嘛。 手机下载一个谷歌身份验证器就可以 。
谷歌身份验证器,我本身是一个基于时间做加密计算然后得出相同结果 本身很简单。
下边在网上查的 可以做一下了解:谷歌身份验证就是基于TOTP算法
TOTP算法,全称为“Time-based One-time Password algorithm”,中文译为基于时间的一次性密码算法。它是一种从共享密钥和当前时间计算一次性密码的算法,已被采纳为Internet工程任务组标准RFC 6238。TOTP是开放身份验证计划(OATH)的基石,并被用于许多双因素身份验证系统。详细的可以百度一下搜索原理,我们这里只是介绍一下使用。
下边是代码 :
import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.Hex;
import org.springframework.util.StringUtils;import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;public class GoogleAuthenticator {/*** 时间前后偏移量 目的解决30秒内有计算有误差不一致的发生*/private static int WINDOW_SIZE = 0;/*** 加密方式,HmacSHA1、HmacSHA256、HmacSHA512*/private static final String CRYPTO = "HmacSHA1";/*** 生成二维码内容** @param secretKey 密钥* @param account 账户名* @param issuer 网站地址(可不写)* @return*/public static String getQrCodeText(String secretKey, String account, String issuer) {String normalizedBase32Key = secretKey.replace(" ", "").toUpperCase();try {return "otpauth://totp/"+ URLEncoder.encode((!StringUtils.isEmpty(issuer) ? (issuer + ":") : "") + account, "UTF-8").replace("+", "%20")+ "?secret=" + URLEncoder.encode(normalizedBase32Key, "UTF-8").replace("+", "%20")+ (!StringUtils.isEmpty(issuer) ? ("&issuer=" + URLEncoder.encode(issuer, "UTF-8").replace("+", "%20")) : "");} catch (UnsupportedEncodingException e) {throw new IllegalStateException(e);}}/*** 检验 code 是否正确** @param secret 密钥* @param code code* @param time 时间戳* @return*/public static boolean checkCode(String secret, long code, long time) {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 = (time / 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.long hash;for (int i = -WINDOW_SIZE; i <= WINDOW_SIZE; ++i) {try {hash = verifyCode(decodedKey, t + i);} catch (Exception e) {return false;}if (hash == code) {return true;}}return false;}/*** 根据时间偏移量计算** @param key* @param t* @return* @throws NoSuchAlgorithmException* @throws InvalidKeyException*/private static long verifyCode(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, CRYPTO);Mac mac = Mac.getInstance(CRYPTO);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 truncatedHash;}public static String getkeyBase32() {// 生成一个随机的密钥字节数组SecureRandom random = new SecureRandom();byte[] keyBytes = new byte[20]; // 一般长度为16、20或32字节random.nextBytes(keyBytes);// 将密钥转换成Base32格式以便用户显示或扫描二维码Base32 base32 = new Base32();String secretKeyBase32 = base32.encodeToString(keyBytes);return secretKeyBase32;}public static void main(String[] args) {
// String secretKeyBase32 = getkeyBase32();String secretKeyBase32 = "YR3TEMNWNWOVMFPFK3BB2SLM2P3IV6MF";System.out.println("加密信息》》》" + secretKeyBase32);System.out.println("拿到这个字符串 二维码工具:去生成二维码图片就可以了" + getQrCodeText(secretKeyBase32, "jxd", "hdjz"));System.out.println(checkCode(secretKeyBase32, Long.parseLong("034944"), System.currentTimeMillis()));}
}
我这个方法,都是基于现成的,不需要额外引入j2totp 等类库 很方便可以拿去用
相关文章:
实现一个Google身份验证代替短信验证
最近才知道公司还在做国外的业务,要实现一个登陆辅助验证系统。咱们国内是用手机短信做验证,当然 这个google身份验证只是一个辅助验证登陆方式。看一下演示 看到了嘛。 手机下载一个谷歌身份验证器就可以 。 谷歌身份验证器,我本身是一个基…...
Spring框架与Spring Boot的区别和联系
引言 Spring框架和Spring Boot都是Java生态中最受欢迎的开源框架,它们各自扮演着不同的角色,帮助开发者构建高效的企业级应用。本教程将从零基础的角度出发,让你轻松理解这两者的区别和联系。 Spring框架简介 Spring框架,简称Spri…...
[OpenCV学习笔记]Qt+OpenCV实现图像灰度反转、对数变换和伽马变换
目录 1、介绍1.1 灰度反转1.2 图像对数变换1.3 图像伽马变换 2、效果图3、代码实现4、源码展示 1、介绍 1.1 灰度反转 灰度反转是一种线性变换,是将某个范围的灰度值映射到另一个范围内,一般是通过灰度的对调,突出想要查看的灰度区间。 S …...
【大数据】Flink学习笔记
文章目录 认识FlinkDocker安装Flink基本概念Flink的特点Flink 和 Spark Streaming 对比 基本使用WordCount实现依赖 批模式代码流模式代码网络流模式代码在web UI上提交代码创建项目[^1]编写代码配置打包在Web UI上提交 Flink 架构系统架构核心概念并行度算子链(Opeartor Chain…...
社交网络的未来:Facebook如何塑造数字社交的下一章
引言 社交网络已成为我们生活中不可或缺的一部分,而Facebook作为其领军者,一直在塑造着数字社交的未来。本文将深入探讨Facebook在未来如何塑造数字社交的下一章,并对社交网络的发展趋势进行展望和分析。 1. 引领虚拟社交的潮流 Facebook将…...
RabbitMQ 延时消息实现
1. 实现方式 1. 设置队列过期时间:延迟队列消息过期 死信队列,所有消息过期时间一致 2. 设置消息的过期时间:此种方式下有缺陷,MQ只会判断队列第一条消息是否过期,会导致消息的阻塞需要额外安装 rabbitmq_delayed_me…...
【Django】枚举类型数据
模型 在模型里主要增加两项内容: 枚举表字段增加choices class Snort(CoreModel):PAGE_TYPE_CHOICES [(1, 失陷主机检测), # 1是保存到数据库里的数据,失陷主机检测是显示在前端的(2, 远程漏洞攻击检测),(3, 可疑流量行为),(4, WEB检测),]page_type…...
java实现https连接总是要报no cipher suites in common
遇到“no cipher suites in common”这样的错误通常意味着客户端和服务器之间没有共同支持的加密套件(Cipher Suite)。这个问题可能由多个原因引起,包括但不限于SSL/TLS配置错误、Java安全策略限制、客户端或服务器不支持的加密算法等。解决这…...
[C++初阶] 爱上C++ : 与C++的第一次约会
🔥个人主页:guoguoqiang 🔥专栏:我与C的爱恋 本篇内容带大家浅浅的了解一下C中的命名空间。 在c中,名称(name)可以是符号常量、变量、函数、结构、枚举、类和对象等等。工程越大,名称…...
STM32技术打造:智能考勤打卡系统 | 刷卡式上下班签到自动化解决方案
文章目录 一、简易刷卡式打卡考勤系统(一)功能简介原理图设计程序设计 哔哩哔哩: https://www.bilibili.com/video/BV1NZ421Y79W/?spm_id_from333.999.0.0&vd_sourcee5082ef80535e952b2a4301746491be0 一、简易刷卡式打卡考勤系统 &…...
module ‘numpy‘ has no attribute ‘int‘
在 NumPy 中,如果遇到了错误提示 "module numpy has no attribute int",这通常意味着正在尝试以错误的方式使用 NumPy 的整数类型。从 NumPy 1.20 版本开始,numpy.int 已经不再是一个有效的属性,因为 NumPy 不再推荐使用…...
MFC(一)搭建空项目
安装MFC支持库 创建空白桌面程序 项目相关设置 复制以下代码 // mfc.h #pragma once #include <afxwin.h>class MyApp : public CWinApp { public:virtual BOOL InitInstance(); };class MyFrame : public CFrameWnd { public:MyFrame();// 消息映射机制DECLARE_…...
OKCC的API资源管理平台怎么用?
API资源管理平台,重点是“资源”管理平台,不是API接口管理平台。 天天讯通推出的API资源管理平台,类似昆石的VOS系统,区别是VOS是SIP资源管理系统,我们的API资源管理平台是API资源管理系统(AXB、AX、回拨AP…...
CentOS 7 安装python 3.7 需要必要的依赖。
在 CentOS 7 上部署 Python 3.7 可以通过源代码编译安装来实现。以下是大致的步骤: 安装必要的依赖: bashCopy Code sudo yum install gcc openssl-devel bzip2-devel libffi-devel 下载 Python 3.7 源代码并进行编译安装: bashCopy Code wg…...
美术馆设计方案优化布局与设施提升观众体验!
如今,美术馆不仅仅是作为展示艺术作品的平台,也是吸引公众参与和创造独特体验的数字艺术体验空间,因此许多传统美术馆在进行翻修改造时,都会更加注重用户体验,并在其中使用大量的多媒体互动,让参观者能够在…...
数据库基础原理
宏观 数据库的实现原理分为四个部分: 网络通信 网络协议 硬盘存储 内存分配 微观 硬盘存储 数据库是持久化的,而持久化如何实现的,我们不难想到磁盘可以持久化存储,所以数据库所有持久化的数据都是以文件形式存在磁盘中的…...
Pandas操作MultiIndex合并行列的Excel,写入读取以及写入多余行及Index列处理,插入行,修改某个单元格的值,多字段排序
Pandas操作MultiIndex合并行列的excel,写入读取以及写入多余行及Index列处理,多字段排序尽量保持原来的顺序 1. 效果图及问题2. 源码参考 今天是谁写Pandas的 复合索引MultiIndex,写的糊糊涂涂,晕晕乎乎。 是我呀… 记录下&#…...
工作总结5
1.taro框架使用map标签出现的错误 这个问题困扰很长时间,在频繁切换页面渲染的时候出现左边不显示,我理解的是变量没有到达map标签的属性上,那我就想是不是setState太慢了,然后又用了变量,本地缓存等,都没有…...
速通汇编(二)汇编mov、addsub指令
一,mov指令 mov指令的全称是move,从字面上去理解,作用是移动(比较确切的说是复制)数据,mov指令可以有以下几种形式 无论哪种形式,都是把右边的值移动到左边 mov 寄存器,数据&#…...
软考 - 系统架构设计师 - 构件组装技术
概念 构件组装是将库中的构件经修改后相互连接,或者将它们和当前开发项目中的软件元素进行连接,最终构成新的目标构件。 构件组装技术是基于构件的软件开发的核心技术,也是构件技术研究的重点和难点。构件组装的目的是利用现有的构件组装成新…...
Paperxie AI 毕业论文写作,助力大学生高效搞定初稿
paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/AIPPThttps://www.paperxie.cn/ai/dissertationhttps://www.paperxie.cn/ai/dissertation 在本科毕业季的朋友圈里,总能刷到这样的动态:凌晨三点的台灯下,对着空白文档发…...
Realistic Vision V5.1 虚拟摄影棚:QT开发跨平台AI图像生成桌面应用
Realistic Vision V5.1 虚拟摄影棚:QT开发跨平台AI图像生成桌面应用 想象一下,你是一位独立摄影师或内容创作者,脑海里有一个绝妙的画面构思——可能是晨曦中穿着复古长裙的少女,也可能是赛博朋克都市里的未来侦探。过去…...
如何用轻量工具实现Windows 11系统深度净化?
如何用轻量工具实现Windows 11系统深度净化? 【免费下载链接】Win11Debloat 一个简单的PowerShell脚本,用于从Windows中移除预装的无用软件,禁用遥测,从Windows搜索中移除Bing,以及执行各种其他更改以简化和改善你的Wi…...
实战避坑!从WMS视角看Android UI线程优化:为什么主线程耗时必掉帧?
从WMS到Choreographer:Android主线程耗时操作导致丢帧的底层原理与实战优化 当你在Android应用中滑动列表时突然出现卡顿,或是界面渲染出现明显延迟,这背后往往隐藏着主线程耗时操作与WMS(WindowManagerService)、Chor…...
YOLO12在工业质检场景:PCB缺陷识别与小目标检测实战案例
YOLO12在工业质检场景:PCB缺陷识别与小目标检测实战案例 1. 引言:当AI质检员遇上电路板 想象一下,你是一家电子厂的质检主管。每天,成千上万块印刷电路板(PCB)从生产线上下来,每一块都需要经过…...
Java 设计模式・策略模式篇:从思想到代码实现
一、行为型模式 在面向对象的世界里,如何优雅地组织对象间的交互、分配职责,是每一位开发者都会反复思考的问题。直接硬编码交互逻辑固然简单,但当业务复杂度上升、对象协作关系变得错综复杂时,这种方式就会让代码变得僵化、难以…...
避坑指南:Double DQN和Dueling DQN在TensorFlow 2.x中的5个常见实现错误
Double DQN与Dueling DQN在TensorFlow 2.x中的五大工程陷阱与解决方案 当你在深夜调试强化学习模型时,是否遇到过这种情况:训练曲线像过山车一样剧烈波动,明明采用了Double DQN或Dueling DQN这些改进算法,效果却比基础DQN还要差&a…...
医学影像与卫星图的救星?深入聊聊JPEG-LS算法在边缘计算设备上的应用优势
JPEG-LS算法:边缘计算时代的医学影像与卫星图像压缩利器 当一台CT扫描仪每秒产生数百张16位深度的医学影像,或一颗遥感卫星每天传回数TB的高清地表数据时,传统的图像压缩方案往往面临两难选择——要么牺牲宝贵的诊断细节,要么耗尽…...
LangChain4j vs Spring AI:Java AI 框架技术选型深度对比与生产落地指南
LangChain4j vs Spring AI:Java AI 框架技术选型深度对比与生产落地指南 摘要:当 Java 团队建设 AI 应用时,真正困难的通常不是“能否调通模型”,而是“如何把 Prompt、RAG、工具调用、可观测性、限流熔断、灰度发布、权限隔离与业务系统稳定地耦合起来”。本文不再停留在 …...
从人工到智能:SubtitleOCR如何实现硬字幕提取的效率革命
从人工到智能:SubtitleOCR如何实现硬字幕提取的效率革命 【免费下载链接】SubtitleOCR 快如闪电的硬字幕提取工具。仅需苹果M1芯片或英伟达3060显卡即可达到10倍速提取。A very fast tool for video hardcode subtitle extraction 项目地址: https://gitcode.com/…...
