动态口令使用场景

  • 服务器登录动态口令验证
  • WEB应用密码登录二次验证
  • 银行转账动态口令

Java实现代码

package org.xbeckoning.commons.util;import org.apache.commons.codec.binary.Base32;
import org.apache.commons.lang3.RandomStringUtils;import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.ByteBuffer;
import java.util.UUID;public class TotpUtils {/** 时间步长,动态口令变化时间周期(单位秒) */private static final int TIME_STEP = 30;/** 动态口令默认长度 */private static final int CODE_DIGITS = 6;/*** 生成唯一密钥** @return*/public static String generateSecretKey() {// UUID + 4位随机字符生成唯一标识String uniqueId = UUID.randomUUID() + RandomStringUtils.randomAlphabetic(4);return new String(new Base32().encode(uniqueId.getBytes()));}/*** 生成一个基于TOTP标准身份验证器识别的字符串* 将该字符串生成二维码可供通用动态密码工具识别,例如:iOS应用(Authy)、微信小程序(二次验证码)** @param user* @param secret* @return*/public static String getQRCodeStr(String user, String secret) {String format = "otpauth://totp/%s?secret=%s";return String.format(format, user, secret);}/*** 生成动态口令** @param secret* @return*/public static String generateTOTP(String secret) {return TotpUtils.generateTOTP(secret, TotpUtils.getCurrentInterval(), CODE_DIGITS);}/*** 生成指定位数的动态口令** @param secret* @param codeDigits* @return*/public static String generateTOTP(String secret, int codeDigits) {return TotpUtils.generateTOTP(secret, TotpUtils.getCurrentInterval(), codeDigits);}/*** 验证动态口令** @param secret* @param code* @return*/public static boolean verify(String secret, String code) {return TotpUtils.verify(secret, code, CODE_DIGITS);}/*** 验证动态口令** @param secret* @param code* @param codeDigits* @return*/public static boolean verify(String secret, String code, int codeDigits) {long currentInterval = TotpUtils.getCurrentInterval();// 考虑到时间延时,需考虑前一个步长的动态密码是否匹配for (int i = 0; i <= 1; i++) {String tmpCode = TotpUtils.generateTOTP(secret, currentInterval - i, codeDigits);if (tmpCode.equals(code)) {return true;}}return false;}/*** 获取动态口令剩余秒数* <p>* 所有口令是基于时间戳计算,因此任何动态口令的剩余有效时间都是一致的** @return*/public static int getRemainingSeconds() {return TIME_STEP - (int) (System.currentTimeMillis() / 1000 % TIME_STEP);}/*** 生成动态口令** @param secret* @param currentInterval* @param codeDigits* @return*/private static String generateTOTP(String secret, long currentInterval, int codeDigits) {if (codeDigits < 1 || codeDigits > 18) {throw new UnsupportedOperationException("不支持" + codeDigits + "位数的动态口令");}byte[] content = ByteBuffer.allocate(8).putLong(currentInterval).array();byte[] hash = TotpUtils.hmacsha(content, secret);// 获取hash最后一个字节的低4位,作为选择结果的开始下标偏移int offset = hash[hash.length - 1] & 0xf;// 获取4个字节组成一个整数,其中第一个字节最高位为符号位,不获取,使用0x7fint binary =((hash[offset] & 0x7f) << 24) |((hash[offset + 1] & 0xff) << 16) |((hash[offset + 2] & 0xff) << 8) |(hash[offset + 3] & 0xff);// 如果所需位数为6,则该值为1000000long digitsPower = Long.parseLong(TotpUtils.rightPadding("1", codeDigits + 1));// 获取当前数值后的指定位数long code = binary % digitsPower;// 将数字转成字符串,不够指定位前面补0return TotpUtils.leftPadding(Long.toString(code), codeDigits);}/*** 获取当前时间戳** @return*/private static long getCurrentInterval() {return System.currentTimeMillis() / 1000 / TIME_STEP;}/*** 向左补足0** @param value* @param length* @return*/private static String leftPadding(String value, int length) {while (value.length() < length) {value = "0" + value;}return value;}/*** 向右补足0** @param value* @param length* @return*/private static String rightPadding(String value, int length) {while (value.length() < length) {value = value + "0";}return value;}/*** 使用HmacSHA1加密** @param content* @param key* @return*/private static byte[] hmacsha(byte[] content, String key) {try {byte[] byteKey = new Base32().decode(key);Mac hmac = Mac.getInstance("HmacSHA1");SecretKeySpec keySpec = new SecretKeySpec(byteKey, "HmacSHA1");hmac.init(keySpec);return hmac.doFinal(content);} catch (Exception e) {e.printStackTrace();}return null;}

Java实现TOTP动态口令验证相关推荐

  1. OTP 动态口令验证

    OTP 动态口令验证. 简介 动态口令(OTP,One-Time Password)又称一次性密码,是使用密码技术实现的在客户端和服务器之间通过共享秘密的一种认证技术,是一种强认证技术,是增强目前静态 ...

  2. 使用google身份验证器实现动态口令验证

    最近有用户反应我们现有的短信+邮件验证,不安全及短信条数限制和邮件收验证码比较慢的问题,希望我们 也能做一个类似银行动态口令的验证方式.经过对可行性的分析及慎重考虑,可以实现一个这样的功能. 怎么实现 ...

  3. android开发动态口令,谷歌动态口令最新版下载-谷歌动态口令验证器v5.00 安卓官方版 - 极光下载站...

    谷歌动态口令安卓版是全新推出的安全性极高的口令软件,有的用户反应自己的谷歌账号会有所不良好的反应,该工具就是为了全面解决这种恶意还打造的验证app,有需要的朋友们可以来试试,极光下载站提供谷歌动态口令 ...

  4. Java使用google身份验证器实现动态口令验证

    google身份认证器服务端key的生成和它生成的随机密码的验证: 客户端和服务器事先协商好一个密钥K,用于一次性密码的生成过程,此密钥不被任何第三方所知道.此外,客户端和服务器各有一个计数器C,并且 ...

  5. java 手机动态口令_动态密码TOTP的Java实现

    一.HOTP HOTP 算法,全称是"An HMAC-Based One-Time Password Algorithm",是一种基于事件计数的一次性密码生成算法,详细的算法介绍可 ...

  6. java利用TOTP算法动态生成一次性密码

    一.HOTP   HOTP 算法,全称是"An HMAC-Based One-Time Password Algorithm",是一种基于事件计数的一次性密码生成算法,详细的算法介 ...

  7. php通过谷歌身份验证实现动态口令

    Google Authenticator,是谷歌推出的一款动态口令工具,解决大家的google账户遭到恶意攻击的问题:许多安全性比较高的网站都会采用这种工具来验证登录或者交易:这个动态口令就是Goog ...

  8. OTP:Java一次动态密码、付款码原理

    1. 什么是OTP 一次性密码(One Time Password,简称OTP),又称"一次性口令",是指只能使用一次的密码. 2. OTP原理 动态密码的产生方式,主要是以时间差 ...

  9. java 动态密码错误_什么是OTP:Java一次动态密码、付款码原理

    1. 什么是OTP 一次性密码(One Time Password,简称OTP),又称"一次性口令",是指只能使用一次的密码. 1 2. OTP原理 动态密码的产生方式,主要是以时 ...

最新文章

  1. 常见的一些功能测试用例
  2. Python 5种方法实现单例模式
  3. 移植U-Boot.1.3.1到S3C2440和S3C2410
  4. videowriter最小的编码格式_cv2.VideoWriter() 指定写入视频帧编码格式
  5. 报错型sql注入原理分析
  6. select超过固定条数后出现滚动条_12万公里的路虎维修,两个小小的胶套损坏,导致两条后轮胎偏磨!...
  7. $().index() 两种用法
  8. 管理九段,你的管理入围“几段”了?
  9. HTML+CSS大学生个人网站作业模板~黑色的html5个人博客网站模板整站下载
  10. MyEclipse10破解工具,crack下载
  11. 文件太多,台式电脑迁移数据到笔记本怎么操作?
  12. Box Cox Transformation
  13. Android版添加phonegap-百度社会化分享插件教程
  14. Android 关于佳博和汉印蓝牙热敏打印机开发,kotlin爬虫app
  15. 使用树莓派构建嵌入式C++调试环境
  16. 计算机英语统考试卷分析,英语期末考试试卷分析与反思
  17. 智力竞赛抢答器Verilog HDL设计
  18. Qt 中十六进制字节流转换为Base64编码
  19. ChatGPT会让程序员失业?ChatGPT:“ 是友军,我不从事任何职业。
  20. 魔兽世界 windows 7 下 界面 问题

热门文章

  1. 百度人脸识别api使用BASE64传输图片一直报错222203
  2. Android开发中dip,dpi,density,px等详解
  3. DCT变换 / DWT变换 ----课堂笔记
  4. 【君思智慧园区】如何打造产业社区?产业社区的打造思路有哪些?
  5. java 夏令时区_土耳其的Java时区(拒绝夏令时)
  6. python怎么退出游戏_当游戏结束条件不满足时,如何退出游戏?
  7. strtol的返回值
  8. wyy课堂cmos模拟设计课学习笔记-bandgap电路设计1
  9. 飘云QQ2007现有BUG解决办法...终于搞定!
  10. 手机外部文件存储_写入/读取文件(SD卡)