仿谷歌驗證 (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);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章