使用OTP动态口令(每分钟变一次)进行登录认证
GIT地址:https://github.com/suyin58/otp-demo
动态码截图:

在对外网开放的后台管理系统中,使用静态口令进行身份验证可能会存在如下问题:
(1) 为了便于记忆,用户多选择有特征作为密码,所有静态口令相比动态口令而言,容易被猜测和破解;
(2) 黑客可以从网上或电话线上截获静态密码,如果是非加密方式传输,用户认证信息可被轻易获取;
(3) 内部工作人员可通过合法授权取得用户密码而非法使用;
静态口令根本上不能确定用户的身份,其结果是,个人可以轻松地伪造一个假身份或者盗用一个已有使用者的身份,给企业造成巨大的经济和声誉损失。本文主要介绍并实现了一种动态口令(OTP)的实现方式。
动态口令(OTP,One-Time Password)又称一次性密码,是使用密码技术实现的在客户端和服务器之间通过共享秘密的一种认证技术,是一种强认证技术,是增强目前静态口令认证的一种非常方便技术手段,是一种重要的双因素认证技术,动态口令认证技术包括客户端用于生成口令产生器的,动态令牌,是一个硬件设备,和用于管理令牌及口令认证的后台动态口令认证系统组成。
otp从技术来分有三种形式, 时间同步、事件同步、挑战/应答。
(1) 时间同步
原理是基于 动态令牌和 动态口令验证服务器的时间比对,基于 时间同步的 令牌,一般每60秒产生一个新口令,要求服务器能够十分精确的保持正确的时钟,同时对其令牌的晶振频率有严格的要求,这种技术对应的终端是硬件令牌。
(2)事件同步
基于事件同步的令牌,其原理是通过某一特定的事件次序及相同的种子值作为输入,通过HASH算法中运算出一致的密码。
(3)挑战/应答
常用于的网上业务,在网站/应答上输入 服务端下发的 挑战码, 动态令牌输入该挑战码,通过内置的算法上生成一个6/8位的随机数字,口令一次有效,这种技术目前应用最为普遍,包括刮刮卡、短信密码、动态令牌也有挑战/应答形式。
使用阿里云身份宝(或者Google Authenticator)时间同步实现OTP动态口令

如上图,是一种基于时间同步的OTP计算方式,是通过客户端和服务器持有相同的密钥并基于时间基数,服务端和客户端采用相同的Hash算法,计算出长度为六位的校验码。当客户端和服务端计算出的校验码相同是,那么验证通过。
由于客户端需要存储密钥和计算校验码的载体,阿里云的身份宝(或者Google 的Authenticator)提供了手机端的APP进行密钥存储和校验码计算。下面我们以这两款客户端为例,实现在应用采用OTP进行权限验证,主要流程如下图:

流程关键代码如下,(更详细代码,请Git下载:https://github.com/suyin58/otp-demo)
1 用户注册:
1.1 生成OTP密钥:
String secretBase32 = TotpUtil.getRandomSecretBase32(64); oper.setOtpSk(secretBase32);
1.2 生成OTP扫描用字符串:
约定字符串格式如下:
- otpauth://totp/[客户端显示的账户信息]?secret=[secretBase32]
String totpProtocalString = TotpUtil.generateTotpString(operCode, host, secretBase32);
1.3 将1.2中生成的字符串生成二维码,通过邮件发送给用户
String host = "otptest@wjs.com"; // 自定义
String totpProtocalString = TotpUtil.generateTotpString(operCode, host, secretBase32);
String filePath = f_temp;
String fileName = Long.toString(System.currentTimeMillis()) + ".png";
try{
QRUtil.generateMatrixPic(totpProtocalString, 150, 150, filePath, fileName);
}catch (Exception e){
throw new RuntimeException("生成二维码图片失败:" + e.getMessage());
}
String content = "用户名:"+operCode+"</br>"
+"系统使用密码 + 动态口令双因素认证的方式登录。</br>请按以下方式激活手机动态口令:</br>安卓用户请点击<a href='http://otp.aliyun.com/updates/shenfenbao.apk'>下载</a>,"
+"</br>苹果手机在AppStore中搜索【身份宝】(Alibaba)。下载安装后,通过扫描以下二维码激活动态口令。</br>"
+"<img src=\"cid:image\">";
EmailBaseLogic emailBaseLogic = new EmailBaseLogic();
// String to, String title, String content, String imagePath
emailBaseLogic.sendWithPic(email,"账户开立通知", content, filePath + "/" + fileName);
1.4 将用户注册信息与1.1的OTP密钥存储到数据库中
数据存储代码(略)
2 客户端工具使用
2.1 下载APP
安卓用户下载地址:http://otp.aliyun.com/updates/shenfenbao.apk
苹果手机在AppStore中搜索【身份宝】(Alibaba),或者Google Authenticator
2.2 扫描二维码
使用下载的APP,扫描1.3邮件中的二维码,客户端获取密钥。APP使用密钥基于时间算出6位校验码(每分钟变化)。

1 用户登录
客户端输入登录用户名、用户密码,以及2.2客户端工具中的6位校验码。
1.1 服务端根据用户名和用户密码获取用户信息和密钥
代码参考略
1.2 服务端使用密钥基于时间算出6位校验码
String secretHex = "";
try {
secretHex = HexEncoding.encode(Base32String.decode(secretBase32));
} catch (Base32String.DecodingException e) {
LOGGER.error("解码" + secretBase32 + "出错,", e);
throw new RuntimeException("解码Base32出错");
} long X = 30; String steps = "0";
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
df.setTimeZone(TimeZone.getTimeZone("UTC")); long currentTime = System.currentTimeMillis() / 1000L;
try {
long t = currentTime / X;
steps = Long.toHexString(t).toUpperCase();
while (steps.length() < 16) steps = "0" + steps; return generateTOTP(secretHex, steps, "6",
"HmacSHA1");
} catch (final Exception e) {
LOGGER.error("生成动态口令出错:" + secretBase32, e);
throw new RuntimeException("生成动态口令出错");
}
1.3 比较客户端和客户端校验码是否一致
代码参考略
其他,Demo中的例子可以使用身份 + 密码,先进行密码验证,在通过动态口令进行二次验证,使系统登录更加安全可靠。
使用OTP动态口令(每分钟变一次)进行登录认证的更多相关文章
- php集成动态口令认证
这篇文章主要为大家详细介绍了php集成动态口令认证,动态口令采用一次一密.用过密码作废的方式来提高安全性能,感兴趣的小伙伴们可以参考一下 大多数系统目前均使用的静态密码进行身份认证登录,但由于静态密码 ...
- 黄聪:OTP动态密码_Java代码实现
OTP认知 动态口令(OTP,One-Time Password)又称一次性密码,是使用密码技术实现的在客户端和服务器之间通过共享秘密的一种认证技术,是一种强认证技术,是增强目前静态口令认证的一种非常 ...
- poptest老李谈动态口令原理
poptest老李谈动态口令原理 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:908 ...
- [Python学习笔记-003] 使用PyOTP获取基于OTOP算法的动态口令
建立安全的VPN连接,不仅需要输入用户名和密码,还需要输入动态口令(token).作为一个懒人,我更喜欢什么手工输入都不需要,既不需要输入password,也不需要输入token.也就是说,只需一个命 ...
- FreeRadius+GoogleAuthenticator实现linux动态口令认证
简介 在运维管理中,服务器的密码管理十分重要.服务器数量少的时候还好说,可以定时来改密码.一旦数量多了,再来改密码就不现实了. 前提 我们假定运维访问服务器是这样的: 创建一个普通用户用于登录服务器, ...
- YS动态口令系统接入流程
动态口令是保护用户账户的一种常见有效手段,即用户进行敏感操作(比如登录)时,需要用户提供此动态生成的口令做二次身份验证,假设用户的口令被盗,如果没有动态口令,也无法进行登录或进行敏感操作,保护了用户的 ...
- 使用google身份验证器实现动态口令验证
最近有用户反应我们现有的短信+邮件验证,不安全及短信条数限制和邮件收验证码比较慢的问题,希望我们 也能做一个类似银行动态口令的验证方式.经过对可行性的分析及慎重考虑,可以实现一个这样的功能. 怎么实现 ...
- Google authenticator 谷歌身份验证,实现动态口令
Google authenticator 谷歌身份验证,实现动态口令 google authenticator php 服务端 使用PHP类 require_once '../PHPGangsta/G ...
- Android WebView访问网站携带登录认证Cookies和动态自定义的cookies
最近项目几个页面要复用微信程序的网页.但是需要调用微网站登录接口,返回Cookies,webview访问需要的网页的时候携带. 并且还需要几个其他的动态改变的cookie,目的是根据这几个动态自定义c ...
随机推荐
- Java设计模式之(建造者模式)
建造者模式:是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 建造者模式通常包括下面几个角色: 1. builder:抽象建造者,给出一个抽象接口,以规范产品对象的各个组 ...
- Linux 练习(1)
1) 新建用户natasha,uid为1000,gid为555,备注信息为"master" useradd -u 1000 -g 555 -c 'master' natasha2) ...
- [Monkey King]
题目描述 在一个森林里住着N(N<=10000)只猴子.在一开始,他们是互不认识的.但是随着时间的推移,猴子们少不了争斗,但那只会发生在互不认识(认识具有传递性)的两只猴子之间.争斗时,两只猴子 ...
- 蓝桥杯-凑算式-java
/* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2016, 广州科技贸易职业学院信息工程系学生 * All rights reserved. * 文件名称: ...
- Excel 数据导入(OleDb)
@using (Html.BeginForm("Student", "Excel", FormMethod.Post, new { enctype = &quo ...
- nginx 日志分割(简单、全面)
Nginx 日志分割 因业务需要做了简单的Nginx 日志分割, 第1章 详细配置如下. #建议在mkdir /home/shell -p 专门写shell 脚本位置 root@localhost ...
- Hive 桶的分区
(一).桶的概念: 对于每一个表(table)或者分区, Hive可以进一步组织成桶(没有分区能分桶吗?),也就是说桶是更为细粒度的数据范围划分.Hive也是 针对某一列进行桶的组织.Hive采用对列 ...
- C#总结(三)DataGridView增加全选列
最近的一个winform的项目中,碰到datagridview控件的第一列添加全选的功能,通常这个功能,有两种实现方式:1. 为控件添加DataGridViewCheckBoxColumn来实现,但是 ...
- Day4-生成器generator
列表生成式 需求:列表[0,1,2,3,4,5,6,7,8,9]每个值加1,如何实现? 方法1:列表追加 >>> a = [0,1,2,3,4,5,6,7,8,9] >> ...
- js中的sort方法
js中原生的sort()采用快排和插入排序算法,根据比较器对数组排序. 默认是将数组元素转为字符串,然后根据Unicode字符集编号的大小排序. charCodeAt(index) 返回指定位置字符的 ...