カテゴリ: Java 更新日: 2026/01/26

JavaのSecureRandomクラスの使い方を完全ガイド!初心者でもわかるセキュアな乱数生成

SecureRandomクラス
SecureRandomクラス

先生と生徒の会話形式で理解しよう

生徒

「Javaでセキュリティの高い乱数を生成する方法ってありますか?」

先生

「はい、JavaにはSecureRandomというクラスが用意されています。このクラスを使うことで、暗号レベルのセキュアな乱数を生成できます。」

生徒

「普通のRandomクラスとどう違うんですか?」

先生

「良い質問ですね。Randomクラスは一般的な用途で使う乱数を生成しますが、セキュリティが求められる場合はSecureRandomを使います。それでは、具体的な使い方を見ていきましょう!」

1. SecureRandomクラスとは?

1. SecureRandomクラスとは?
1. SecureRandomクラスとは?

Javaでセキュリティの高い乱数を生成したい場合に登場するのがSecureRandomクラスです。見た目は普通の乱数と同じように使えますが、内部では予測がとても難しい仕組みで乱数を作り出します。そのため、パスワードやトークン、認証コードなど、セキュリティが重要な場面で利用されます。まずはインポートして使える形にしましょう。


import java.security.SecureRandom;

「普通のRandomではダメなの?」と疑問に思う人も多いですが、Randomは予測される可能性があります。一方、SecureRandomは予測がほぼ不可能なので、安全な乱数が必要なアプリケーションでは標準的に使われています。

簡単なサンプル(まずは動かしてみる)


public class SimpleSecureRandom {
    public static void main(String[] args) {
        SecureRandom sr = new SecureRandom();
        int number = sr.nextInt(10); // 0〜9 の乱数
        System.out.println("セキュアな乱数: " + number);
    }
}

上の例では、0〜9の中からランダムに1つ数字を取り出しています。見た目は簡単ですが、中身はしっかりとセキュアな乱数です。普段のJavaプログラムと同じ感覚で書けるので、初心者でも安心して使えます。

2. SecureRandomの基本的な使い方

2. SecureRandomの基本的な使い方
2. SecureRandomの基本的な使い方

SecureRandomを使った乱数の生成はとてもシンプルです。まずは、最も基本的な数字の乱数を作る例から見てみましょう。難しい設定は不要で、インスタンスを作って数字を取得するだけでOKです。


import java.security.SecureRandom;

public class SecureRandomExample {
    public static void main(String[] args) {
        SecureRandom secureRandom = new SecureRandom();  // セキュアな乱数生成器
        int number = secureRandom.nextInt(10);           // 0〜9 の中からランダムで1つ
        System.out.println("セキュアな乱数: " + number);
    }
}

実行結果


セキュアな乱数: 7

このサンプルでは、必ず0〜9の範囲で整数が1つ出力されます。見た目は普通の乱数ですが、内部では予測しづらい仕組みで数字が作られており、認証コードや使い捨てトークンのような安全性が求められる用途に向いています。

もし、複数回乱数を取りたい場合も同じ方法で簡単に実装できます。下の例では3回連続で乱数を出力しています。


public class MultiSecureRandom {
    public static void main(String[] args) {
        SecureRandom sr = new SecureRandom();
        for (int i = 0; i < 3; i++) {
            System.out.println("乱数: " + sr.nextInt(10));
        }
    }
}

初心者でも扱いやすい書き方なので、まずはコピーして実行してみるのがおすすめです。数値がランダムに切り替わる様子を見るだけでも、SecureRandomの使い方が自然と理解できるようになります。

3. バイト配列を使った乱数の生成

3. バイト配列を使った乱数の生成
3. バイト配列を使った乱数の生成

SecureRandomクラスでは、整数以外にもバイト配列に直接乱数を生成することが可能です。これは、暗号学的なキーやトークンを生成するときに非常に便利です。


import java.security.SecureRandom;

public class SecureRandomBytes {
    public static void main(String[] args) {
        SecureRandom secureRandom = new SecureRandom();
        byte[] randomBytes = new byte[16];
        secureRandom.nextBytes(randomBytes);
        
        System.out.print("生成されたバイト配列: ");
        for (byte b : randomBytes) {
            System.out.printf("%02x ", b);
        }
    }
}

実行結果


生成されたバイト配列: 3e a5 7f d1 2b 4c 93 20 e4 7a c8 9f 1e 7b a0 5d 

この例では、16バイトの乱数を生成し、16進数で表示しています。バイト配列を用いることで、パスワード生成やAPIキーなどに利用することができます。

4. SecureRandomのシード値について

4. SecureRandomのシード値について
4. SecureRandomのシード値について

SecureRandomクラスでは、シード(初期値)を設定することができます。通常、SecureRandomはデフォルトのシード値を使用しますが、特定のシード値を設定することで再現性のある乱数を生成することが可能です。


import java.security.SecureRandom;

public class SecureRandomWithSeed {
    public static void main(String[] args) {
        byte[] seed = {1, 2, 3, 4, 5};
        SecureRandom secureRandom = new SecureRandom(seed);
        int randomNumber = secureRandom.nextInt(100);
        System.out.println("シード値を使った乱数: " + randomNumber);
    }
}

実行結果


シード値を使った乱数: 42

シード値を設定すると、毎回同じ乱数を得ることができるため、テスト環境などで役立ちます。

5. SecureRandomを使ったパスワード生成の例

5. SecureRandomを使ったパスワード生成の例
5. SecureRandomを使ったパスワード生成の例

最後に、SecureRandomを使ったパスワード生成の実装例を紹介します。アルファベットと数字を組み合わせたランダムなパスワードを生成します。


import java.security.SecureRandom;

public class SecureRandomPassword {
    private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    private static final int PASSWORD_LENGTH = 12;

    public static void main(String[] args) {
        SecureRandom secureRandom = new SecureRandom();
        StringBuilder password = new StringBuilder();

        for (int i = 0; i < PASSWORD_LENGTH; i++) {
            int index = secureRandom.nextInt(CHARACTERS.length());
            password.append(CHARACTERS.charAt(index));
        }

        System.out.println("生成されたパスワード: " + password);
    }
}

実行結果


生成されたパスワード: Xy8Z1dAe4QpB

このプログラムでは、ランダムに選んだ12文字のパスワードを生成します。SecureRandomを使うことで、セキュリティの高いパスワードを生成することが可能です。

6. 初期化とアルゴリズムの選び方(getInstanceStrongの注意点)

6. 初期化とアルゴリズムの選び方(getInstanceStrongの注意点)
6. 初期化とアルゴリズムの選び方(getInstanceStrongの注意点)

new SecureRandom() は通常の用途に十分です。より強度の高い実装を明示したい場合は SecureRandom.getInstanceStrong() を使えますが、環境によってはエントロピー待ちでブロックする可能性があるため、高負荷・低レイテンシ要件の本番処理では慎重に評価しましょう。まずはデフォルトで問題ないかを確認し、必要に応じてプロバイダやアルゴリズムをログに出して観測するのがおすすめです。


import java.security.SecureRandom;

public class InitAndAlgo {
    public static void main(String[] args) throws Exception {
        // 推奨: まずはデフォルト
        SecureRandom def = new SecureRandom();
        System.out.println("Default: " + def.getAlgorithm() + " / " + def.getProvider().getName());

        // 強力だがブロックの可能性あり: 事前検証が必須
        SecureRandom strong = SecureRandom.getInstanceStrong();
        System.out.println("Strong : " + strong.getAlgorithm() + " / " + strong.getProvider().getName());
    }
}
  • 実装はJDKやOSに依存します。アルゴリズム名・プロバイダ名を把握しておくと運用で役立ちます。
  • ベンチマークと監視を行い、必要に応じてインスタンスの使い分けを検討しましょう。

7. 固定シードはテスト専用:setSeedの正しい理解

7. 固定シードはテスト専用:setSeedの正しい理解
7. 固定シードはテスト専用:setSeedの正しい理解

固定シードでの初期化(例:new SecureRandom(seed))は再現性重視のテスト用です。本番のセキュアな乱数生成では固定シードを使わないでください。setSeed() は「置き換え」ではなく既存の状態に追加で混ぜるためのものとして設計されています(追加のエントロピーを与える用途)。


import java.security.SecureRandom;
import java.nio.charset.StandardCharsets;

public class SeedingBestPractice {
    public static void main(String[] args) {
        SecureRandom sr = new SecureRandom(); // 本番はこれで十分
        // 追加のエントロピーが外部から得られる場合のみ、追加入力として混ぜる
        byte[] extraEntropy = "human-typed-rare-event".getBytes(StandardCharsets.UTF_8);
        sr.setSeed(extraEntropy); // 追加ミキシング(必須ではない)
        System.out.println(sr.nextInt());
    }
}
  • 本番で固定シードはNG(予測可能になります)。
  • setSeed() は追加エントロピーの混入用途。通常は不要です。

8. トークンやキーの長さと安全なエンコード(Base64 / Hex)

8. トークンやキーの長さと安全なエンコード(Base64 / Hex)
8. トークンやキーの長さと安全なエンコード(Base64 / Hex)

セッションIDやCSRFトークンなどの秘密値には、最低でも16バイト(128ビット)以上、推奨は32バイト(256ビット)の乱数を使い、URLやヘッダで扱いやすい形式にエンコードします。URLに載せる場合は Base64 URL-safe が便利です。ログや可読性重視なら16進表記(Hex)も有効です。


import java.security.SecureRandom;
import java.util.Base64;
// JDK 17+ なら HexFormat も使えます: import java.util.HexFormat;

public class TokenEncoder {
    public static void main(String[] args) {
        SecureRandom sr = new SecureRandom();

        // 推奨サイズ: 32バイト
        byte[] tokenBytes = new byte[32];
        sr.nextBytes(tokenBytes);

        // URL-safe Base64(パディングなし)
        String urlToken = Base64.getUrlEncoder().withoutPadding().encodeToString(tokenBytes);
        System.out.println("URL-safe token: " + urlToken);

        // Hex(JDK 17+)
        // String hexToken = HexFormat.of().formatHex(tokenBytes);
        // System.out.println("Hex token    : " + hexToken);
    }
}
  • 文字集合を自作すると偏りや実装ミスが起きやすいので、まずは Base64/Hex を検討。
  • 秘匿情報はログ出力・コンソール出力を最小化し、マスキングを徹底しましょう。

9. よくある落とし穴と実践チェックリスト

9. よくある落とし穴と実践チェックリスト
9. よくある落とし穴と実践チェックリスト
  • RandomMath.random()を使わない。 セキュアな乱数は必ず SecureRandom
  • 固定シードはテスト専用。本番では自動シードに任せる。
  • バイト値の「剰余(%)」で文字集合に割り当てると偏りの原因。nextInt(bound) を使う。
  • 十分なバイト長を確保(16〜32バイト)。取り回しは Base64/Hex を使用。
  • 高頻度アクセスではスレッドごとにインスタンスを持つなど、競合による遅延を避ける設計を。

例:6桁のワンタイムコードを均等分布で生成(ゼロ埋め)。


import java.security.SecureRandom;

public class OtpExample {
    public static void main(String[] args) {
        SecureRandom sr = new SecureRandom();
        int code = sr.nextInt(1_000_000); // 0〜999999 の一様乱数
        String otp = String.format("%06d", code); // ゼロ埋めで6桁固定
        System.out.println("OTP: " + otp);
    }
}

まとめ

まとめ
まとめ

この記事では、JavaのSecureRandomクラスについて、基本的な使い方から応用例まで詳しく解説しました。SecureRandomは、暗号学的に安全な乱数を生成するためのクラスで、通常のRandomクラスよりも強力なセキュリティが求められる場面で非常に有効です。 例えば、パスワードやAPIキーの生成、トークンの発行など、セキュアなランダムデータが必要なシステムでは必須の機能と言えるでしょう。
SecureRandomは単に乱数を生成するだけでなく、バイト配列やシード値を使った多様な乱数生成も可能です。また、特定のシード値を設定することで再現性のある乱数も生成できるため、テストやデバッグの場面でも役立ちます。

さらに、SecureRandomを使ったパスワード生成の方法を学ぶことで、より安全な認証情報を作成できるスキルが身につきました。この記事を参考にして、セキュリティが重要なプロジェクトにおいてSecureRandomを効果的に活用してください。

パスワード生成のもう一つの例

最後に、もう少し応用的なパスワード生成プログラムを紹介します。特殊文字を含めたパスワードを生成してみましょう。


import java.security.SecureRandom;

public class AdvancedPasswordGenerator {
    private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+";
    private static final int PASSWORD_LENGTH = 16;

    public static void main(String[] args) {
        SecureRandom secureRandom = new SecureRandom();
        StringBuilder password = new StringBuilder();

        for (int i = 0; i < PASSWORD_LENGTH; i++) {
            int index = secureRandom.nextInt(CHARACTERS.length());
            password.append(CHARACTERS.charAt(index));
        }

        System.out.println("強力なパスワード: " + password);
    }
}

実行結果


強力なパスワード: Ab8&xP2#Rt!7gLk$

このプログラムでは、特殊文字を含めた16文字のパスワードを生成します。セキュリティレベルをさらに高めたい場合に活用してください。

先生と生徒の振り返り会話

生徒

「今回SecureRandomクラスについて詳しく学べました。暗号レベルの乱数を使うとセキュリティが向上するんですね!」

先生

「その通りです。SecureRandomを活用すれば、安全なパスワードやトークンの生成が可能になります。セキュリティが求められる開発には必須のスキルですね。」

生徒

nextBytes()nextInt()などのメソッドも便利でした。特にバイト配列を使う方法は新鮮でした。」

先生

「バイト配列を使えば、より多様なセキュリティ用途に対応できます。次は実際のプロジェクトで使ってみてください。」

生徒

「ありがとうございます!これでセキュアなアプリケーションの開発に一歩近づきました!」

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

JavaのSecureRandomとRandomの違いは何ですか?暗号学的に安全な乱数生成という点で、セキュリティ強度や予測困難性、パスワード生成・APIキー生成・トークン生成・暗号鍵作成などの用途でどう使い分ければよいのかを初心者向けに知りたいです。

SecureRandomは暗号学的に安全な乱数生成に最適化されたJavaのクラスで、予測されにくい乱数を提供します。Randomは一般的な用途向けで、セキュリティ目的のパスワード生成やトークン生成には推奨されません。記事では、セキュアな乱数が必要な場面(パスワード・APIキー・トークン・暗号鍵など)ではSecureRandomを使う、と明確に位置づけています。

SecureRandomの基本的な使い方を知りたいです。Javaで0から9の範囲のセキュアな乱数を生成する考え方や、初心者がつまずきやすいポイントを含めて、乱数生成の流れをわかりやすく教えてください。

SecureRandomの基本は、インスタンスを用意し、範囲を与えて乱数を取り出すことです。記事の例では0から9の範囲を扱い、範囲指定により目的に合った値を得られると説明しています。予測困難でセキュアな乱数を前提に、認証・認可・ログインなど安全性が求められる処理に向くという理解が第一歩になります。

Javaの基礎を最初から体系的に学びたい人には、 初心者向けで定評のある定番入門書がこちらです。

スッキリわかるJava入門 第4版をAmazonで見る

※ Amazon広告リンク

カテゴリの一覧へ
新着記事
New1
Spring
SpringDataJPAのJPAクエリメソッド「EndingWith」の使い方を完全ガイド!初心者向け解説
更新記事
New2
Spring
SpringDataJPAのJPAクエリメソッド「StartingWith」の使い方を完全ガイド!初心者向け解説
更新記事
New3
Spring
SpringDataJPAのJPAクエリメソッド「NotLike」の使い方を完全ガイド!初心者向け解説
更新記事
New4
Spring
SpringDataJPAのJPAクエリメソッド「Like」の使い方を完全ガイド!初心者向け解説
更新記事
人気記事
No.1
Java&Spring記事人気No1
Spring
Spring BootとJavaの互換性一覧!3.5/3.4/3.3はJava 21・17に対応してる?
No.2
Java&Spring記事人気No2
Java
JavaのBooleanクラスの使い方を完全ガイド!初心者でもわかる真偽値の操作
No.3
Java&Spring記事人気No3
Java
JavaのIOExceptionクラス徹底解説!初心者向けファイル入出力エラー対策ガイド
No.4
Java&Spring記事人気No4
JSP
JSPの基本タグ一覧と使い方まとめ!実務で使えるタグを紹介
No.5
Java&Spring記事人気No5
JSP
JSPでif文・for文を使う方法!初心者でもわかるJavaとの違いと使い方
No.6
Java&Spring記事人気No6
Spring
SpringのBindingResultを完全ガイド!初心者でもわかる入力チェックとエラー処理
No.7
Java&Spring記事人気No7
Spring
SpringのModelクラスとaddAttributeメソッドの使い方を完全ガイド!初心者でも安心
No.8
Java&Spring記事人気No8
Spring
SpringDataJPAのJPAクエリメソッド「EndingWith」の使い方を完全ガイド!初心者向け解説