C# Tips | セキュリティ:ランダムTokenを生成する

C# C#
スポンサーリンク
スポンサーリンク

ランダムトークン生成は「安全な認証・セッション管理の土台」です

読者のみなさんが業務システムを開発する際、 ランダムなトークン(Token)を安全に生成することは必須のセキュリティ要件です。

トークンは次のような場面で使われます。

  • パスワードリセット用 URL
  • メール認証リンク
  • API のアクセストークン
  • CSRF トークン
  • セッション ID
  • 一時的な認証コード

これらはすべて「推測されてはいけない」ため、 暗号学的に安全なランダム値を使う必要があります。

ここでは、初心者でも理解できるように、 実務で使える C# のランダムトークン生成ユーティリティを丁寧に解説します。

ランダムトークン生成の目的は「推測不可能な値を作ること」です

なぜ推測不可能である必要があるのか?

攻撃者は次のような方法でトークンを破ろうとします。

  • 総当たり攻撃(Brute Force)
  • 連番・規則性の推測
  • 弱い乱数生成器の悪用

もしトークンが「規則的」「短い」「弱い乱数」で作られていたら、 攻撃者は簡単に推測できます。

そこで必要なのが「暗号学的に安全な乱数」です

C# では Random クラスは絶対に使ってはいけません。 Random は「予測可能な乱数」であり、セキュリティ用途には不向きです。

代わりに使うべきなのは:

  • RandomNumberGenerator(System.Security.Cryptography)

これは暗号学的に安全な乱数を生成します。

強力なトークンの条件を理解する(初心者向けにかみ砕く)

強力なトークンは次の条件を満たします。

  • 十分な長さ(最低 32〜64 バイト)
  • 暗号学的に安全な乱数を使用
  • Base64 や Hex などで安全に文字列化
  • 推測できる規則性がない

これらを満たすことで、 攻撃者がトークンを推測するのが極端に難しくなります。

実務で使えるランダムトークン生成ユーティリティ(テンプレート)

そのままコピペで使えるテンプレートです。

using System;
using System.Security.Cryptography;

public static class SecureTokenUtility
{
    /// <summary>
    /// 暗号学的に安全なランダムトークンを生成します。
    /// </summary>
    /// <param name="byteLength">生成するバイト数(推奨:32〜64)</param>
    public static string GenerateToken(int byteLength = 32)
    {
        // 指定バイト数のランダム値を生成
        byte[] randomBytes = RandomNumberGenerator.GetBytes(byteLength);

        // Base64 で文字列化(URL に使う場合は Base64Url に変換する)
        return Convert.ToBase64String(randomBytes);
    }

    /// <summary>
    /// URL に安全に埋め込める Base64Url トークンを生成します。
    /// </summary>
    public static string GenerateUrlSafeToken(int byteLength = 32)
    {
        byte[] randomBytes = RandomNumberGenerator.GetBytes(byteLength);

        string base64 = Convert.ToBase64String(randomBytes);

        // Base64Url 形式に変換(URLで安全)
        return base64.Replace("+", "-").Replace("/", "_").Replace("=", "");
    }
}
C#

トークン生成の使い方(実務コード例)

string token = SecureTokenUtility.GenerateToken(32);
Console.WriteLine(token);

// URL に使う場合
string urlToken = SecureTokenUtility.GenerateUrlSafeToken(32);
Console.WriteLine(urlToken);
C#

トークンの長さはどう決めるべきか?(深掘り)

32 バイト(256bit)

  • 一般的なセキュリティ用途
  • パスワードリセット
  • メール認証
  • CSRF トークン

64 バイト(512bit)

  • 高セキュリティ用途
  • API アクセストークン
  • OAuth の state パラメータ
  • セッション ID

16 バイト(128bit)

  • 最低限。
  • ただし業務システムでは推奨しません。

Random クラスを使ってはいけない理由(重要ポイント)

初心者がやりがちな誤り:

C#

これは絶対に使ってはいけません。

理由:

  • Random は「予測可能」
  • シード値が弱い
  • 総当たり攻撃に弱い
  • セキュリティ用途に不向き

攻撃者は Random の生成パターンを簡単に推測できます。

トークンを Base64 にする理由(深掘り)

Base64 のメリット

  • 安全に文字列化できる
  • URL に埋め込みやすい
  • 文字化けしない
  • すべての環境で扱いやすい

Hex(16進数)でも良い

ただし、Hex は Base64 より長くなるため、 URL やメールでは Base64 の方が扱いやすいです。

トークン生成で絶対にやってはいけないこと

  • Random クラスを使う
  • 短すぎるトークンを使う(8〜16 バイトなど)
  • 規則性のあるトークンを使う
  • トークンをログに出力する
  • トークンを平文で長期間保存する

これらはすべて攻撃者に突破されます。

実務的ベストプラクティス

  • RandomNumberGenerator を必ず使う
  • 最低 32 バイト以上のトークンを生成する
  • URL に使う場合は Base64Url に変換する
  • トークンは短期間で失効させる(有効期限を設ける)
  • トークンはハッシュ化して保存することも検討する
  • ログにトークンを出力しない

まとめ:ランダムトークン生成は「安全な認証の基盤」です

ランダムトークン生成の本質は次の 3 つです。

  • 暗号学的に安全な乱数を使う
  • 十分な長さを確保する
  • 安全な形式(Base64 / Base64Url)で文字列化する

これらを守ることで、 攻撃者がトークンを推測するのを極端に難しくできます。

読者のみなさんが業務システムを開発する際、 このユーティリティを使うだけでセキュリティレベルが大幅に向上し、 ユーザーの安全を確実に守ることができます。

タイトルとURLをコピーしました