LOFTER for ipad —— 让兴趣,更有趣

点击下载 关闭
google身份验证器
xiaospace 2017-03-16

maven包:

          <dependency>

               <groupId>org.apache.httpcomponents</groupId>

              <artifactId>httpclient</artifactId>

              <version>4.4.1</version>

          </dependency>

代码:

/**

 * Project Name:google-auth

 * File Name:GoogleAuth.java

 * Package Name:cn.easysw.google

 * Date:2017年2月28日上午10:27:44

 * Copyright (c) 2017, www.windo-soft.com All Rights Reserved.

 *

*/

package cn.easysw.google;

import java.net.URLEncoder;

import java.util.Date;

import java.util.concurrent.TimeUnit;

import javax.crypto.Mac;

import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base32;

import org.apache.http.client.utils.URIBuilder;

/**

 * ClassName:GoogleAuth <br/>

 * Function: TODO ADD FUNCTION. <br/>

 * Reason: TODO ADD REASON. <br/>

 * Date: 2017年2月28日 上午10:27:44 <br/>

 *

 * @author xiaospace

 * @version

 * @since JDK 1.7

 * @see

 */

public class GoogleAuth {

     private static final String TOTP_URI_FORMAT = "https://chart.googleapis.com/chart?chs=200x200&chld=M%%7C0&cht=qr&chl=%s";

     private static final String HMAC_HASH_FUNCTION = "HmacSHA1";

     /**

      * getPassword:验证二维码. <br/>

      *

      * @author xiaospace

      * @param secret 密钥

      * @param nowDate 时间

      * @param correction

      *            处理网络传输偏差时间

      * @return 返回验证码

      * @since JDK 1.7

      */

     public static int getPassword(String secret, long nowDate, long correction) {

          long tm = (nowDate - correction) / TimeUnit.SECONDS.toMillis(30);

          try {

              return getCode(new Base32().decode(secret.toUpperCase()), tm);

          } catch (Exception e) {

              return -99;

          }

     }

     /**

      * getCodeUrl:得到二维码url. <br/>

      *

      * @author xiaospace

      * @param appName<放置app名称>

      *            不能为空且不能有':' 

      * @param user <账户名称>

      *            不能为空

      * @param secret

      *            密钥

      * @return 返回二维码url

      * @since JDK 1.7

      */

     public static String getCodeUrl(String appName, String user, String secret) {

          try {

              return String.format(TOTP_URI_FORMAT, URLEncoder.encode(getUrl(appName, user, secret), "UTF-8"));

          } catch (Exception e) {

              return null;

          }

     }

     private static String formatLabel(String issuer, String accountName) {

          StringBuilder sb = new StringBuilder();

          sb.append(issuer);

          sb.append(":");

          sb.append(accountName);

          return sb.toString();

     }

     private static String getUrl(String appName, String user, String secret) {

          URIBuilder uri = new URIBuilder().setScheme("otpauth").setHost("totp").setPath("/" + formatLabel(appName, user))

                   .setParameter("secret", secret);

          uri.setParameter("issuer", appName);

          return uri.toString();

     }

     /**

      * getCode:google具体实现算法. <br/>

      *

      * @author xiaospace

      * @param key

      * @param tm

      * @return

      * @throws Exception

      * @since JDK 1.7

      */

     private static int getCode(byte[] key, long tm) throws Exception {

          byte[] data = new byte[8];

          long value = tm;

          for (int i = 8; i-- > 0; value >>>= 8) {

              data[i] = (byte) value;

          }

          SecretKeySpec signKey = new SecretKeySpec(key, HMAC_HASH_FUNCTION);

          Mac mac = Mac.getInstance(HMAC_HASH_FUNCTION);

          mac.init(signKey);

          byte[] hash = mac.doFinal(data);

          int offset = hash[hash.length - 1] & 0xF;

          long truncatedHash = 0;

          for (int i = 0; i < 4; ++i) {

              truncatedHash <<= 8;

              truncatedHash |= (hash[offset + i] & 0xFF);

          }

          truncatedHash &= 0x7FFFFFFF;

          truncatedHash %= (int) Math.pow(10, 6);// 除以10^6

          return (int) truncatedHash;

     }

     public static void main(String[] args) {

          // ---------------url-----------

          System.out.println(getCodeUrl("***APP***", "***账号***", "XXXX XXXX XXXX XXXXX"));

          // ---------------得到密码--------

          System.out.println(getPassword("XXXX XXXX XXXX XXXXX", System.currentTimeMillis(),0));

     }

}


nonsense:

主要缘由是因为印象笔记和google二次验证都用到了google的身份验证器,就想看看相关代码。当然没有再深入看算法~只是一个签名的过程(较为知名)~

下载地址:

ios:

https://itunes.apple.com/us/app/google-authenticator/id388497605?mt=8

android:

https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=zh-CN



推荐文章
评论(0)
分享到
转载我的主页