開発の最終段階でハッシュ化することをお薦めします。

今回は、Javaで安全にパスワードをハッシュ化する方法について、新人エンジニア向けに解説していきます。

「パスワードってどうやって暗号化すればいいの?」
「ハッシュって何?戻せるの?」

…そんなあなたの疑問に、ライブラリの使い方から安全な設計の考え方まで、しっかり説明していきます!


なぜパスワードをハッシュ化する必要があるの?

パスワードをそのまま保存してしまうと、万が一データベースが流出したときに、利用者全員のパスワードが漏れてしまいます。

そのため、次のような仕組みが必要です:

  • ハッシュ化:元の文字列から別の文字列に変換(復元不可)
  • ソルト:ランダムな追加文字列でレインボーテーブル攻撃を防ぐ
  • ストレッチング:繰り返しハッシュして総当たり攻撃に耐える

Apache Commons Codecとは?

Apache Commons Codecは、Javaでハッシュやエンコードを簡単に行えるライブラリです。

代表的なハッシュ関数

アルゴリズム特徴
MD5古くて高速、非推奨
SHA-1こちらも非推奨
SHA-256安全性が高く、CRYPTRECにも掲載されている推奨アルゴリズム

導入手順

  1. 公式サイトから最新版の.jarをダウンロード
  2. WEB-INF/lib フォルダに配置
  3. 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」ではなく、「未来にも通用すること」が大切です。
今日学んだハッシュの知識を活かして、安全で信頼されるアプリケーションを作っていきましょう!

質問があればいつでもどうぞ!

最後までお読みいただきありがとうございます。