ログイン認証時のトークンを毎回ランダムに変化させる(APOP的アプローチ)

戻る

毎回ハッシュ値を変化させることにより、途中でトークンが盗まれたとしても
それは二度と利用できない。
また仮にハッシュ値生成のロジックが判明しても、パスワードの推定は現実的には不可能になる。
ただトークンの生成のためのキーは、サーバ側が毎回ランダムに生成し、各セッションで固有のものに
しなければいけません。クライアントがそのキーを類推できるものではいけない。

下記はあくまで簡略版です。


$ java -cp . VariableTokenGenerator
token = 02251a80ef8eb2cd1123dbff5b99bcde0bb9814d
流れてきた電文:
        token = 02251a80ef8eb2cd1123dbff5b99bcde0bb9814d
        currentTime = 2005-11-19 01:55:06
        uid = Xokans2

認証成功

token = 0ee9e84f83a55caa5e33067311b3f8f1cd83cb01
流れてきた電文:
        token = 0ee9e84f83a55caa5e33067311b3f8f1cd83cb01
        currentTime = 2005-11-19 01:55:07
        uid = Xokans2

認証成功

token = 406ff45e4cfacfcb138b96afe9a80caef06b471b
流れてきた電文:
        token = 406ff45e4cfacfcb138b96afe9a80caef06b471b
        currentTime = 2005-11-19 01:55:08
        uid = Xokans2

認証成功

token = f05c1869f33d1e9e5c48a313cbef7bb052d28ee1
流れてきた電文:
        token = f05c1869f33d1e9e5c48a313cbef7bb052d28ee1
        currentTime = 2005-11-19 01:55:10
        uid = Xokans2

認証失敗!

token = f9cc790826483fb79b1586fd1b9ac9957d4a4837
流れてきた電文:
        token = f9cc790826483fb79b1586fd1b9ac9957d4a4837
        currentTime = 2005-11-19 01:55:11
        uid = Xokans2

認証失敗!


::::::::::::::
AuthenticationManager.java
::::::::::::::
/**
* $Id: VariableTokenGenerator.html,v 1.1 2009/06/22 16:12:02 kishi Exp kishi $
*/

public class AuthenticationManager {

    private String uid = "Xokans2";
    private String pwd = "98s%43";

    public boolean authenticate( String token, String currentTime, String uid ) {

        System.out.println( "流れてきた電文: " );
        System.out.println( "\t" + "token = " + token );
        System.out.println( "\t" + "currentTime = " + currentTime );
        System.out.println( "\t" + "uid = " + uid );
        System.out.println();

        String comparableToken = TSUtil.sha1Digest( currentTime + "\t" + uid + "\t" + pwd );

        return token.equals( comparableToken );
    }
}
::::::::::::::
TSUtil.java
::::::::::::::
import java.util.*;
import java.security.MessageDigest;

/**
* $Id: VariableTokenGenerator.html,v 1.1 2009/06/22 16:12:02 kishi Exp kishi $
*/
public class TSUtil {

    public static String getCurrentDateTime() {
        Calendar calendar = Calendar.getInstance();

        StringBuffer sb = new StringBuffer();
        sb.append( calendar.get( Calendar.YEAR ) );

        int mm = calendar.get( Calendar.MONTH ) + 1;
        sb.append( "-" + zeroPad( mm ) );

        int dd = calendar.get( Calendar.DATE );
        sb.append( "-" + zeroPad( dd ) );

        int hh = calendar.get( Calendar.HOUR_OF_DAY );
        sb.append( " " + zeroPad( hh ) );

        int mi = calendar.get( Calendar.MINUTE );
        sb.append( ":" + zeroPad( mi ) );

        int ss = calendar.get( Calendar.SECOND );
        sb.append( ":" + zeroPad( ss ) );

        return sb.toString();
    }

    private static String zeroPad( int number ) {
        return ( number < 10 ) ? "0" + number : String.valueOf( number );
    }

    /** 文字列からSHA1ハッシュ値を求めて16進で表示する
    @param str 入力文字列
    @return ハッシュ値
    */
    static public String sha1Digest( String str ) {
        StringBuffer result = new StringBuffer( );
        try {
            MessageDigest md = MessageDigest.getInstance( "SHA1" ); /* MD5のときは"MD5"とすればいいですよ! */
            md.update( str.getBytes() );
            byte[] digest = md.digest();

            for ( int i = 0; i < digest.length; i++ ) {
                if ( ( digest[ i ] & 0x0ff ) / 16 == 0 ) {
                    result.append( "0" );
                }
                result.append( Integer.toHexString( digest[ i ] & 0x0ff ) );
            }

        } catch ( Exception e ) {}

        return result.toString();
    }

}
::::::::::::::
VariableTokenGenerator.java
::::::::::::::
import java.util.*;
import java.security.MessageDigest;

/**
* $Id: VariableTokenGenerator.html,v 1.1 2009/06/22 16:12:02 kishi Exp kishi $
* It is aumostly simular to APOP mechanism
*/

public class VariableTokenGenerator {

    public static void main( String[] args ) {


        AuthenticationManager am = new AuthenticationManager();

        VariableTokenGenerator vtg = new VariableTokenGenerator();

        String uid = "Xokans2";
        String pwd = "98s%43";

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

            String currentTime = TSUtil.getCurrentDateTime();

            if ( i < 3 ) {
                // 成功のパターン
                pwd = "98s%43";
            } else {
                //失敗のパターン
                pwd = "98s%431000";
            }

            String token = vtg.generateToken( currentTime, uid, pwd );

            System.out.println( "token = " + token );

            boolean status = am.authenticate( token, currentTime, uid );

            if ( status ) {
                System.out.println( "認証成功" );
            } else {
                System.out.println( "認証失敗!" );
            }
            System.out.println();

            try {
                Thread.sleep( 1000 );
            } catch ( Exception e ) {}
        }

    }


    public String generateToken( String currentTime, String uid, String pwd ) {

        String source = currentTime + "\t" + uid + "\t" + pwd;

        return TSUtil.sha1Digest( source );
    }
}
戻る inserted by FC2 system