zoukankan      html  css  js  c++  java
  • 仿谷歌验证 (Google Authenticator) 的一种 Java 实现

    Google Authenticator 的原理是服务器随机生成一个密钥并保存并告知客户端。用户需要登陆时客户端根据密钥和时间戳通过一种算法生成一个6位数字的密码。本文使用 java.util.zip.CRC32 模仿 Google Authenticator 实现此功能。

        /**
         * 生成验证码
         * @param secret: 密钥
         * @param timeMinute: 时间戳(分钟)
         * @param codeLength: 验证码长度
         * @return 指定长度的数字
         */
        public static String generateCode(String secret, long timeMinute, int codeLength) {
            String key = secret + timeMinute;
            CRC32 crc32 = new CRC32();
            crc32.update(key.getBytes());
            String crc32ValueStr = String.valueOf(crc32.getValue());
            return crc32ValueStr.substring(crc32ValueStr.length() - codeLength); // 可以改成其他规则
        }
    
        /***
         * 校验验证码
         * @param secret: 密钥
         * @param verifyCode: 待校验验证码
         * @param expireMinute
         * @return
         */
        public static boolean verifyCode(String secret, String verifyCode, int codeLength, int expireMinute) {
            long timeMillisecond = System.currentTimeMillis();
            long timeMinute = minuteByMillisecond(timeMillisecond);
    
            for (int i = -expireMinute; i <= expireMinute; ++i) {
                String code = generateCode(secret, timeMinute + i, codeLength);
                if(code.equals(verifyCode)) {
                    return true;
                }
            }
            return false;
        }
    
        /***
         * 获取时间戳(分钟)
         * @param timeMillisecond: 时间戳(毫秒)
         * @return
         */
        private static long minuteByMillisecond(long timeMillisecond) {
            return timeMillisecond / (1000 * 60);
        }
    

    使用:

        final int CODE_LENGTH = 6;
        final int CODE_EXPIRE_MINUTE = 1;
        final String SECRET = "YOUR SECRET";
    
        long timeMillisecond = System.currentTimeMillis();
        long timeMinute = minuteByMillisecond(timeMillisecond);
        String code = generateCode(SECRET, timeMinute, CODE_LENGTH);
        boolean result = verifyCode(SECRET, code, CODE_LENGTH, CODE_EXPIRE_MINUTE);
    
  • 相关阅读:
    UDP的坏处
    进程控制块(Process Control Block, PCB)
    分布式中一些关键概念的解释
    线程池的设计实现
    [原创] 同步、异步、阻塞、非阻塞详解
    常用场景对文件状态的影响
    echo使用说明,参数详解
    Linux下源码安装ffmpeg及ffmpeg的简单使用说明
    127.0.0.1、0.0.0.0和本机IP地址的区别和使用
    链路层的简介和MTU
  • 原文地址:https://www.cnblogs.com/victorbu/p/14821251.html
Copyright © 2011-2022 走看看