ログイン認証時のトークンを毎回ランダムに変化させる(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 );
}
}
戻る