Skip to content

Instantly share code, notes, and snippets.

@seyan
Created April 12, 2011 06:41
Show Gist options
  • Save seyan/915057 to your computer and use it in GitHub Desktop.
Save seyan/915057 to your computer and use it in GitHub Desktop.
ソルトを用いたパスワードのハッシュ化:レインボークラックなどへの対策
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;
}
}
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