- Published on
平文のパスワードとソルトから安全なパスワードを作成する
- Authors
 - Name
- Kikusan
 
 
package password;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
public class EncryptionPlayGround {
    public static void main(String[] args) {
        String securePass1 = getSecurePassword("password", "userid01");
        String securePass2 = getSecurePassword("password", "userid01");
        String securePass3 = getSecurePassword("password", "userid02");
        String securePass4 = getSecurePassword("p@ssword", "userid02");
        System.out.println(securePass1);
        System.out.println(securePass2);
        System.out.println(securePass3);
        System.out.println(securePass4);
    }
    /** パスワードを安全にするためのアルゴリズム */
    private static final String ALGORITHM = "PBKDF2WithHmacSHA256";
    /** ストレッチング回数 */
    private static final int STRETCHING_COUNT = 10000;
    /** 生成される鍵の長さ */
    private static final int KEY_LENGTH = 256;
    /**
     * 平文のパスワードとソルトから安全なパスワードを生成し、返却する
     *
     * @param String:password 平文のパスワード
     * @param String:salt ソルト(userid)
     * @return String:securePassword
     */
    public static String getSecurePassword(String password, String salt) {
        char[] passCharAry = password.toCharArray();
        // ソルト値のハッシュ化
        byte[] hashedSalt = getHashedSalt(salt);
        // パスワード,ソルト値, ストレッチ回数, 鍵の長さを指定したキー仕様を設定
        PBEKeySpec keySpec = new PBEKeySpec(passCharAry, hashedSalt, STRETCHING_COUNT, KEY_LENGTH);
        SecretKeyFactory skf;
        try {
            //暗号化・復号オブジェクト
            skf = SecretKeyFactory.getInstance(ALGORITHM);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        SecretKey secretKey;
        try {
            // 安全なパスワード生成
            secretKey = skf.generateSecret(keySpec);
        } catch (InvalidKeySpecException e) {
            throw new RuntimeException(e);
        }
        byte[] passByteAry = secretKey.getEncoded();
        // 生成されたバイト配列を16進数の文字列に変換
        StringBuilder sb = new StringBuilder(64);
        for (byte b : passByteAry) {
            sb.append(String.format("%02x", b & 0xff));
        }
        return sb.toString();
    }
    /**
     * ソルトをハッシュ化して返却する
     * ※ハッシュアルゴリズムはSHA-256を使用
     *
     * @param String:salt ソルト
     * @return byte[]:hashedSalt
     */
    private static byte[] getHashedSalt(String salt) {
        MessageDigest md;
        try {
            md = MessageDigest.getInstance("SHA-256");
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        md.update(salt.getBytes());
        return md.digest();
    }
}