前言
说到帐号安全,当下国内很多网络服务例如银行、游戏、淘宝等 ,除了正确的帐号密码之外,常常还需要额外给你发一条手机短信验证码,以此进一步确认你是帐号的真正主人,这就是两步验证的一种实现方式。本次的任务内容就是使用Java模拟二次验证码(动态令牌)是如何进行实现,在模拟的过程中我明白了二次验证码(也叫两步验证)的实现原理,在此进行记录。
任务描述:生成唯一的64位密钥并将密钥保存下来便于之后的测试,通过密钥来实现每隔一段时间就变化一次的动态数字,创建账户信息并且生成OTPAUTH协议字符串链接的二维码,使用微信小程序或支付宝小程序搜索:二次验证码,使用小程序扫描该二维码,如果扫描成功,则会看到动态令牌出在了手机上并且会有圆圈显示倒计时失效的进度提示,将出现的动态令牌在Java程序中与通过当前密钥生成的二次验证码进行对比,验证动态生成的二维码是否正确。
一、什么是动态令牌?
动态口令是根据专门的算法生成一个不可预测的随机数字组合,一个密码使用一次有效,被广泛运用在网银、网游、电信运营商、电子政务、企业等应用领域。 动态口令是一种安全便捷的帐号防盗技术,可以有效保护交易和登录的认证安全,采用动态口令就无需定期修改密码,安全省心,从而在最基本的密码认证这一环节保证了系统的安全性。解决因口令欺诈而导致的重大损失,防止恶意入侵者或人为破坏,解决由口令泄密导致的入侵问题。 动态令牌即是用来生成动态口令终端。
和短信验证码一样道理,本文的动态令牌也是两步验证中的一种,也是相当于给帐号多加了一次验证,除了在输入正确的账号和密码之外,用户同样还需要额外输入一个每隔一段时间就会自动变化一次的6位数字(两步验证码)才能完成登录或其它功能。所以即使用户的帐号和密码不慎泄露了,别人在没有这个数字验证码时也是无法登录到被泄露信息的用户的账号的,这可以大大提高破解的难度和帐号的安全性。
二、使用的Jar包
1. 生成二维码Jar包
这里我将com.google.zxing的二维码生成工具进行了封装,只留下了一个方法接口make方法
2. Apache Commons Codec
这个jar包当中使用到的类有实现Base32和Base64编码的两个工具类
3. 项目工具类
使用到的工具类中主要用到的有湘王老师给的四个工具类:
- 十六进制编码工具类
- Base32编码工具类
- 生成OTPAUTH协议等各种参数的工具类
4. 下载链接
下载链接:https://pan.baidu.com/s/1P2NWKClHXAj7TRFzAlc5Bg
提取码:xhzy
三、IDEA导入外部Jar包
四、代码测试
1. 生成OTPAUTH协议等信息
packagecom.shijimo.token; importcom.shijimo.token.util.OTPAuthUtil; importqr.CreateQR; publicclassMain { publicstaticvoidmain(String[] args) { // write your code hereSystem.out.println("Hello,World!"); // 生成64位密钥StringsecretKey=OTPAuthUtil.generateSecret(64); System.out.println("生成动态密钥:"+secretKey); // 生成账户名Stringaccount="YkForever"; // 生成OTP协议的路径StringtotpURI=OTPAuthUtil.generateTotpURI(account, secretKey); System.out.println("生成的协议路径为:"+totpURI); CreateQR.make(350,350,totpURI,"D:/qr.png"); } }
在这里生成了64位密钥、OTPAUTH的账户名字和协议路径以及二维码的存储地址
2. 微信小程序扫描结果
将账户添加到小程序中后会有口令的显示
3. 测试口令是否正确
packagecom.shijimo.token; importcom.shijimo.token.util.OTPAuthUtil; importjava.util.Scanner; /*** @author Dream_飞翔* @date 2021/10/29* @time 22:16* @email 1072876976@qq.com*/publicclassTestToken { publicstaticvoidmain(String[] args) { // 动态验证生成的口令是否正确Stringsecret="自动生成的64位密钥"; // 小程序中显示的动态令牌Stringcode="716471"; booleanresult=OTPAuthUtil.verify(secret, code); System.out.println("动态口令是否正确:"+result); } }
总结
以上便是二次验证码的实现过程,相较于短信验证码来说,手机短信验证码和两步验证的目的和作用基本一致,不过很多的 (国外) 网络服务并不支持发送手机短信验证码,主要是短信成本高,而且有安全性风险 (比如 2G 网络下黑客可以利用 GSM 漏洞监听截取到用户的手机号码和短信内容)。而本文所说的二步验证是指虚拟 MFA,或者说是“身份验证器”,是基于时间和加密算法生成“每 30 秒变化一次的 6 位数字验证码”,也叫做 TOTP (Time-Based One-time Password) 或 OTP 一次性密码。它的优点是使用时无需联网、仅需时间进行计算、速度快、可离线使用、没有额外成本、算法协议公开通用,开发和使用上都很简单,可以用小型硬件 (实体的密码器) 或纯软件 APP 来实现,因此更多的网站会支持这种方式。