Created
April 12, 2011 06:41
-
-
Save seyan/915057 to your computer and use it in GitHub Desktop.
ソルトを用いたパスワードのハッシュ化:レインボークラックなどへの対策
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import static org.junit.Assert.assertFalse; | |
import java.io.UnsupportedEncodingException; | |
import java.security.MessageDigest; | |
import java.security.NoSuchAlgorithmException; | |
import org.apache.commons.logging.Log; | |
import org.apache.commons.logging.LogFactory; | |
import org.junit.Test; | |
public class P327Test { | |
private static final Log LOG = LogFactory.getLog(P327Test.class.getName()); | |
/** ハッシュアルゴリズム */ | |
private static final String ALG = "SHA-256"; | |
/** ソルトに用いる固定時文字列(サイト毎に変更してください) */ | |
private static final String FIXEDSALT = "aafsafrevgadsfergvadsefg44wefKYTJRAaawf356"; | |
@Test | |
public void testGetPasswordHash() throws Exception{ | |
String userId1 = "0001"; | |
String userId2 = "0002"; | |
String pass1 = "password"; | |
String pass2 = "password"; | |
//同じパスワードでもユーザIDにより違うハッシュ値が得られることを確認 | |
assertFalse( getPasswordHash(userId1, pass1).equals( getPasswordHash(userId2, pass2) )); | |
} | |
/** | |
* パスワードにソルトを追加したデータのハッシュ値を取得、ソルトの生成にはユーザIDを入力とする関数を用いる。 | |
* @param userId | |
* @param password | |
* @return | |
*/ | |
public String getPasswordHash(String userId, String password){ | |
return getHash(password, getSalt(userId) ); | |
} | |
/** | |
* 引数で与えた文字列にソルトを連結してハッシュ値を取得 | |
* @param target | |
* @param salt | |
* @return | |
*/ | |
private String getHash(String target, String salt){ | |
return getHash(target + salt); | |
} | |
/** | |
* 引数で与えた文字列のハッシュ値を取得 | |
* @param target | |
* @return | |
*/ | |
private String getHash(String target){ | |
String hash = null; | |
try { | |
MessageDigest md = MessageDigest.getInstance(ALG); | |
md.update(target.getBytes()); | |
byte[] digest = md.digest(); | |
//byte[] -> String | |
hash = new String(digest, "UTF-8"); | |
} catch (NoSuchAlgorithmException e) { | |
LOG.error(e.getLocalizedMessage(), e); | |
} catch (UnsupportedEncodingException e) { | |
LOG.error(e.getLocalizedMessage(), e); | |
} | |
return hash; | |
} | |
private String getSalt(String userId){ | |
return userId + FIXEDSALT; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import static org.junit.Assert.assertNotSame; | |
import java.security.MessageDigest; | |
import org.junit.Test; | |
// レビュー後&ストレッチング追加 | |
public class P327Test2 { | |
/** ハッシュアルゴリズム */ | |
private static final String ALG = "SHA-256"; | |
/** ソルトに用いる固定時文字列(サイト毎に変更してください) */ | |
private static final byte[]FIXEDSALT = "aafsafrevgadsfergvadsefg44wefKYTJRAaawf356".getBytes(); | |
/** ストレッチングの回数 */ | |
private static final int STRETCHCOUNT = 1000; | |
@Test | |
public void testGetPasswordHash() throws Exception{ | |
String userid1 = "0001"; | |
String userid2 = "0002"; | |
String pass1 = "password"; | |
String pass2 = "password"; | |
assertNotSame(getHash(userid1, pass1), getHash(userid2, pass2)); | |
} | |
private String getHash(String userid, String password) throws Exception{ | |
MessageDigest md = MessageDigest.getInstance(ALG); | |
md.update(FIXEDSALT); | |
md.update(userid.getBytes()); | |
byte[] digest = md.digest(password.getBytes()); | |
//ストレッチング! | |
for(int i=1; i < STRETCHCOUNT; i++){ | |
digest = md.digest(digest); | |
} | |
// byte[] -> String | |
return new String(digest, "UTF-8"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment