Java使用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中的例子可以使用身份 + 密码,先进行密码验证,在通过动态口令进行二次验证,使系统登录更加安全可靠。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java动态口令登录实现过程详解

    1.实现一个ItsClient 客户端用来实例化调用验证功能 public class ItsClient { private static final String routing = "/v1.0/sectoken/otp_validation"; // ! HTTPS消息验证地址 private String httpsVerifyUrl = ""; // ! otp ipAddr private String ipAddr = ""; /

  • java使用google身份验证器实现动态口令验证的示例

    最近有用户反应我们现有的短信+邮件验证,不安全及短信条数限制和邮件收验证码比较慢的问题,希望我们也能做一个类似银行动态口令的验证方式.经过对可行性的分析及慎重考虑,可以实现一个这样的功能. 怎么实现呢,是自己开发一个这样的app?这样成本太高了,为了节约成本,我们使用互联网使用比较多的google身份验证器.使用它,我们只需要开发服务端就可以了. google身份验证器的原理是什么呢?客户端和服务器事先协商好一个密钥K,用于一次性密码的生成过程,此密钥不被任何第三方所知道.此外,客户端和服务器各

  • Java使用OTP动态口令(每分钟变一次)进行登录认证

    GIT地址:https://github.com/suyin58/otp-demo 动态码截图: 在对外网开放的后台管理系统中,使用静态口令进行身份验证可能会存在如下问题: (1) 为了便于记忆,用户多选择有特征作为密码,所有静态口令相比动态口令而言,容易被猜测和破解: (2) 黑客可以从网上或电话线上截获静态密码,如果是非加密方式传输,用户认证信息可被轻易获取: (3) 内部工作人员可通过合法授权取得用户密码而非法使用: 静态口令根本上不能确定用户的身份,其结果是,个人可以轻松地伪造一个假身份

  • php集成动态口令认证

    大多数系统目前均使用的静态密码进行身份认证登录,但由于静态密码容易被窃取,其安全性无法满足安全要求. 动态口令采用一次一密.用过密码作废的方式防止了密码被窃取带来的安全问题. 动态口令分为HOTP(基于事件计数的动态口令,RFC4226).TOTP(基于时间计数的动态口令,RFC6238).OCRA(挑战应答式动态口令,RFC6287)等方式. 本文介绍了集成TOTP方式的动态口令认证的方案,PHP框架采用Thinkphp3.2.3,动态口令生成器使用的是google authtication.

  • Java实现JDK动态代理的原理详解

    目录 概念 案例 静态代理 JDK动态代理模式 原理分析 真相大白 概念 代理:为控制A对象,而创建出新B对象,由B对象代替执行A对象所有操作,称之为代理.一个代理体系建立涉及到3个参与角色:真实对象(A),代理对象(B),客户端. 其中的代理对象(B)起到中介作用,连通真实对象(A)与客户端,如果进一步拓展,代理对象可以实现更加复杂逻辑,比如对真实对象进行访问控制. 案例 需求:员工业务层接口调用save需要admin权限,调用list不需要权限,没权限调用时抛出异常提示. 静态代理 /**

  • java使用JDBC动态创建数据表及SQL预处理的方法

    本文实例讲述了java使用JDBC动态创建数据表及SQL预处理的方法.分享给大家供大家参考,具体如下: 这两天由于公司的需求,客户需要自定义数据表的字段,导致每张表的字段都不是固定的而且很难有一个通用的模板去维护,所以就使用JDBC动态去创建数据表,然后通过表的字段动态添加数据,数据的来源主要是用户提供的Excel直接导入到数据库中. 如果考虑到字段的类型,可以通过反射的机制去获取,现在主要用户需求就是将数据导入到数据库提供查询功能,不能修改,所以就直接都使用String类型来处理数据更加便捷.

  • java 利用java反射机制动态加载类的简单实现

    如下所示: ////////////////// Load.java package org.bromon.reflect; import java.util.ArrayList; import java.util.List; public class Load implements Operator { @Override public List<?> act(List<?> params) { // TODO Auto-generated method stub List<

  • java 1.8 动态代理源码深度分析

    JDK8动态代理源码分析 动态代理的基本使用就不详细介绍了: 例子: class proxyed implements pro{ @Override public void text() { System.err.println("本方法"); } } interface pro { void text(); } public class JavaProxy implements InvocationHandler { private Object source; public Jav

  • 通过java反射机制动态调用某方法的总结(推荐)

    如下: public Object invokeMethod(String className, String methodName, Object[] args) throws Exception{ Class ownerClass = Class.forName(className); Object owner = ownerClass.newInstance(); Class[] argsClass = new Class[args.length]; for (int i = 0, j =

  • 浅谈Java注解和动态代理

    本文主要介绍Java中与注解和动态代理有关的部分知识,接下来我们看看具体内容. Annotation(注解) 其实就是代码里的特殊标记, 它用于替代配置文件,也就是说,传统方式通过配置文件告诉类如何运行,有了注解技术后,开发人员可以通过注解告诉类如何运行. 1. 三个基本的Annotation: Override:限定重写父类方法, 该注解只能用于方法 Deprecated:用于表示某个程序元素(类, 方法等)已过时 SuppressWarnings:抑制编译器警告. 2.自定义Annotati

随机推荐