二要素認証ソリューション

二要素認証とは何ですか?

人気話す、一般的な認証は、これは、パスワード認証のための唯一の要因である、ユーザ名/パスワードの方法である、二要素の増加は、セキュリティを強化する要素認証以外の何ものでもありません。

一般的なソリューション

  • SMS
  • 郵便
  • 音声による電話
  • TOTPソリューション

最初の三つのプログラムは、それらはすべて類似していました。検証サーバ、サーバの後に利用者にSMS、電子メールや電話の方法、ランダムなパスワードを介してユーザに配信ランダムパスワードのアルゴリズムによって生成されたサーバー側は、ログオン資格情報などの二要素認証を完了しました。しかし、そこに事業会社のためのテキストメッセージや電話音声は、いくつかの非インターネットアプリケーションに加えて、公衆網を介してではないかもしれないが、一定のコストである。この場合、TOTPが良い二要素認証ソリューションであること。

TOTPとは何ですか?

これは、タイムスタンプに基づいてワンタイムパスワードアルゴリズムを表し、時間ベースのワンタイムパスワードの省略形です。

私たちはファンタジー西の旅を果たした場合は、上の将军令不慣れすべきではない、これはTOTPに基づく製品です。

OTP

導入TOTP前に、最初に導入OTP

ワンタイムパスワードの速記は、ワンタイムパスワードを表します。

OTP(K,C) = Truncate(HMAC-SHA-1(K,C))

ここで、キーストリングのKを表す、HMAC-SHA-1 DO HMAC SHA-1で表される; Cは、乱数を表す数です。

暗号化された文字列のための関数は、いくつかのフィールドと文字列を取って暗号化されたデジタル、取られている切り捨てます。

暗号化されたHMAC-SHA-1モードでは、以下を達成するために切り捨てされます。

  • HMAC-SHA-1暗号化された20バイトの暗号化された文字列の長さを与えます。
  • 標準オフセット暗号化された文字列としたバイトの下位4ビットを要する20バイトの暗号化された文字列の最後のバイトを取ります。
  • 開始オフセット索引4つのバイトを得るためによれば、ビッグエンディアン(下位アドレスに上位バイト)の整数の実施形態により構成されています。
  • インターセプト後整数6または8文字列に変換されます。
 public static String generateOTP(String K,
                                      String C,
                                      String returnDigits,
                                      String crypto){
        int codeDigits = Integer.decode(returnDigits).intValue();
        String result = null;
 
        // K是密码
        // C是产生的随机数
        // crypto是加密算法 HMAC-SHA-1
        byte[] hash = hmac_sha(crypto, K, C);
        // hash为20字节的字符串
 
        // put selected bytes into result int
        // 获取hash最后一个字节的低4位,作为选择结果的开始下标偏移
        int offset = hash[hash.length - 1] & 0xf;
 
        // 获取4个字节组成一个整数,其中第一个字节最高位为符号位,不获取,使用0x7f
        int binary =
                ((hash[offset] & 0x7f) << 24) |
                ((hash[offset + 1] & 0xff) << 16) |
                ((hash[offset + 2] & 0xff) << 8) |
                (hash[offset + 3] & 0xff);
        // 获取这个整数的后6位(可以根据需要取后8位)
        int otp = binary % 1000000;
        // 将数字转成字符串,不够6位前面补0
        result = Integer.toString(otp);
        while (result.length() < codeDigits) {
            result = "0" + result;
        }
        return result;
    }

返された結果は、動的パスワードの数を確認することです。

HOTP

私たちは、乱数にパラメータCのちょうど1 OTP、HOTPの基本原則を知っています

式を変更します。

HOTP(K、C)=切捨て(HMAC-SHA-1(K、C))

HOTP:与えられたカウントにOTPを生成します

すなわち:Cは、引数として、動的パスワードを取得します。

SHA2を使用して一般的なHOTP所定のハッシュ関数、すなわち:SHA-256やSHA-512 [SHA2]同期検証ハッシュ関数に基づいてイベントを行います。

詳細TOTP

TOTPタイムスタンプによって生成された番号にだけ、パラメータC。

TOTP(K,C) = HOTP(K,C) = Truncate(HMAC-SHA-1(K,C))

TOTPはC.計算したタイムスタンプと異なっています

C = (T - T0) / X;

Tは現在のUnixタイムスタンプを表し

ゼロT0一般的な値です。

X時間ステップの数を表し、それは動的なパスワードよりも多くを言うことですが、長い時間のために生成され、この時間間隔は、ステップの時間Xの数は、システムのデフォルトは30秒です。

例えば:

T0 = 0;

X = 30。

T = 30〜59、C = 1; 59から30は、30秒を一致動的パスワードを表します。

T = 60〜89、C = 2; 59から30は、30秒を一致動的パスワードを表します。

異なるメーカーが異なるの時間ステップを使用します。

  • 時間の数は、使用アリババ宝アイデンティティは60秒です手順。
  • むしろシールドトークンを使用して、時間ステップの数は、60秒です。
  • Googleの認証の時間ステップ数は30秒です。
  • 時間ステップのトークンテンセント数は60秒です。

アプリケーション

多くのクライアントが記載されている上記の達成があります。サーバー側の実装ライブラリは一見も非公式達成され、比較的小さいです。ここでは、お勧めのJava実装ライブラリプライベートライブラリ、心の友だけで、自分のラインとホイールです。

ここで認識に基づくライブラリーは、いくつかのデモコードは、参照のみを目的として与えられています。

package com.github.chenqimiao.util;

import java.text.MessageFormat;

import com.warrenstrange.googleauth.GoogleAuthenticator;
import com.warrenstrange.googleauth.GoogleAuthenticatorConfig;
import com.warrenstrange.googleauth.GoogleAuthenticatorConfig.GoogleAuthenticatorConfigBuilder;
import com.warrenstrange.googleauth.GoogleAuthenticatorKey;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

/**
 * @Auther: chenqimiao
 * @Date: 2019/8/26 22:58
 * @Description: refer https://github.com/wstrange/GoogleAuth
 */
@Slf4j
public class GoogleAuthenticatorUtils {
    // 前缀
    private static final String DEFAULT_USER_PREFIX = "TOTP_USER:";
    // 用户名|密钥|发行者
    public static final String QRCODE_TEMPLATE = "otpauth://totp/" + DEFAULT_USER_PREFIX + "{0}?secret={1}&issuer={2}";
    // 默认的发行者
    public static final String DEFAULT_ISSUER = "DAS_TOTP";

    private static final GoogleAuthenticatorConfig DEFAULT_CONFIG;

    static {
        GoogleAuthenticatorConfigBuilder builder = new GoogleAuthenticatorConfigBuilder();

        // Do something here if you want to set config for GoogleAuthenticator

        DEFAULT_CONFIG = builder.build();
    }


    public static String createQrCodeContent(String username, String secret) {
        return createQrCodeContent(username, secret, DEFAULT_ISSUER);
    }

    public static String createQrCodeContent(String username, String secret, String issuer) {
        return MessageFormat.format(QRCODE_TEMPLATE, username, secret, issuer);
    }

    public static String createSecret() {
        return createSecret(DEFAULT_CONFIG);
    }

    public static String createSecret(GoogleAuthenticatorConfig config) {
        GoogleAuthenticator gAuth = new GoogleAuthenticator(config);
        final GoogleAuthenticatorKey key = gAuth.createCredentials();
        return key.getKey();
    }

    public static boolean verify(Integer totpPwd, String secret) {

        return verify(totpPwd, secret, DEFAULT_CONFIG);
    }

    public static boolean verify(Integer totpPwd, String secret, GoogleAuthenticatorConfig config) {
        GoogleAuthenticator gAuth = new GoogleAuthenticator(config);
        return gAuth.authorize(secret, totpPwd);
    }

    public static Integer getTotpPassword(String secret) {
        return getTotpPassword(secret, DEFAULT_CONFIG);
    }

    public static Integer getTotpPassword(String secret, GoogleAuthenticatorConfig config) {
        GoogleAuthenticator gAuth = new GoogleAuthenticator(config);
        return gAuth.getTotpPassword(secret);
    }

    @SneakyThrows
    public static void main(String args[]) {
        String secret = createSecret();
        String qrcodeContent = createQrCodeContent("chenqimiao", secret);
        System.out.println("qrcodeContent is " + qrcodeContent);

        Integer totpPwd = getTotpPassword(secret);
        System.out.println("Current totp password is " + totpPwd);

        boolean result = verify(totpPwd, secret);
        System.out.println("result is " + result);

    }

qrcodeContent二次元コードを使用して、二次元コードツールによって生成することができるGoogle認証を二次元コードをスキャンした後、それはユーザバインドオーセンティケータと同等です。

おすすめ

転載: www.cnblogs.com/think-in-java/p/11443014.html