※開発の最終段階でハッシュ化することをお薦めします。
今回は、Javaで安全にパスワードをハッシュ化する方法について、新人エンジニア向けに解説していきます。
「パスワードってどうやって暗号化すればいいの?」
「ハッシュって何?戻せるの?」
…そんなあなたの疑問に、ライブラリの使い方から安全な設計の考え方まで、しっかり説明していきます!
なぜパスワードをハッシュ化する必要があるの?
パスワードをそのまま保存してしまうと、万が一データベースが流出したときに、利用者全員のパスワードが漏れてしまいます。
そのため、次のような仕組みが必要です:
- ハッシュ化:元の文字列から別の文字列に変換(復元不可)
 - ソルト:ランダムな追加文字列でレインボーテーブル攻撃を防ぐ
 - ストレッチング:繰り返しハッシュして総当たり攻撃に耐える
 
Apache Commons Codecとは?
Apache Commons Codecは、Javaでハッシュやエンコードを簡単に行えるライブラリです。
代表的なハッシュ関数
| アルゴリズム | 特徴 | 
|---|---|
| MD5 | 古くて高速、非推奨 | 
| SHA-1 | こちらも非推奨 | 
| SHA-256 | 安全性が高く、CRYPTRECにも掲載されている推奨アルゴリズム | 
導入手順
- 公式サイトから最新版の
.jarをダウンロード WEB-INF/libフォルダに配置- Javaで
import org.apache.commons.codec.digest.DigestUtils;を追加 
サンプル①:SHA-256でパスワードをハッシュ化する
import org.apache.commons.codec.digest.DigestUtils;
public class DigestUtilsTest {
    public static void main(String[] args) {
        String plainPassword = "123456789";
        // シンプルなハッシュ
        String hashed = DigestUtils.sha256Hex(plainPassword);
        System.out.println("ハッシュ(単純): " + hashed);
        // ソルト付きハッシュ(推奨)
        String salt = "randomSalt123";
        String saltedHash = DigestUtils.sha256Hex(plainPassword + salt);
        System.out.println("ハッシュ(ソルト付き): " + saltedHash);
    }
}
実行結果の例:
ハッシュ(単純): 15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225  
ハッシュ(ソルト付き): ab03db0c39851456931b33c525bf70aa4998172865c9adebf930894c4fe8e51f
注意! 単純なハッシュはレインボーテーブル(逆引き辞書攻撃)で破られます。
ソルト(ランダムな文字列)を必ず加えましょう!
サンプル②:ストレッチング(ハッシュの繰り返し)
import org.apache.commons.codec.digest.DigestUtils;
public class DigestUtilsTest2 {
    public static void main(String[] args) {
        String password = "123456789";
        // ストレッチング(10000回)
        for (int i = 0; i < 10000; i++) {
            password = DigestUtils.sha256Hex(password);
        }
        System.out.println("ストレッチング結果: " + password);
    }
}
ストレッチングとは?
同じデータに繰り返しハッシュをかけることで、攻撃の計算コストを上げる技術です。
よくある質問(FAQ)
Q1:ハッシュ化されたパスワードは元に戻せますか?
→ 戻せません!
ハッシュは「一方向関数」と呼ばれ、暗号化とは異なり復号はできません。
Q2:ログイン時のパスワード確認はどうするの?
→ ユーザーが入力したパスワードに同じソルトとハッシュ処理をかけて、データベースのハッシュ値と比較します。
Q3:ソルトはどう作る?
import java.security.SecureRandom;
public class SaltGenerator {
    public static String generateSalt(int length) {
        SecureRandom random = new SecureRandom();
        StringBuilder salt = new StringBuilder(length);
        String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        for (int i = 0; i < length; i++) {
            salt.append(chars.charAt(random.nextInt(chars.length())));
        }
        return salt.toString();
    }
}
まとめ
| 機能 | 説明 | 
|---|---|
DigestUtils.sha256Hex() | 文字列をSHA-256でハッシュ化 | 
| ソルト | 同じパスワードでも違うハッシュにするための追加文字列 | 
| ストレッチング | 複数回ハッシュで安全性アップ | 
| 保存すべき情報 | ハッシュ値とソルト(ユーザーごとに異なるもの) | 
今後の学習の指針
- SHA-512やPBKDF2、bcryptなどのより安全なハッシュ技術にも触れてみよう
 - ソルトとストレッチングの設計パターンを比較してみよう
 - 認証処理を行うサーバーサイドのアーキテクチャ(Spring Securityなど)にも挑戦してみよう
 - OWASP(セキュリティのベストプラクティス)にも目を通そう!
 
セキュリティは「今できていればOK」ではなく、「未来にも通用すること」が大切です。
今日学んだハッシュの知識を活かして、安全で信頼されるアプリケーションを作っていきましょう!
質問があればいつでもどうぞ!