パスワード・UUID・ハッシュ・トークンの違いとは? ランダム文字列 8種の正体と使い分けガイド

システム開発をしていると、550e8400-e29b-41d4-a716-446655440000eyJhbGciOiJIUzI1NiJ9... のような「ランダムっぽい文字列」に頻繁に出会います。UUID、パスワード、ハッシュ、トークン、API キー……見た目はどれも似ていますが、設計思想と用途はまったく違います

この記事では、開発現場でよく使われる 8 種類のランダム風文字列を「なぜ存在するのか」「何を守るのか」という視点で整理します。それぞれの正体を理解すれば、「どの場面でどれを使うべきか」が自然と判断できるようになります。

8 種類の比較一覧

まず、全体像をつかむために一覧表を見てみましょう。

種類主な用途秘密性可逆性生成方法特徴
UUID一意な識別不要ランダム / 時刻衝突しない ID
パスワード本人認証必須本人のみ人間が作成記憶前提の秘密
ハッシュ同一性の検証不要不可逆数学関数デジタル指紋
トークン認証・認可必須場合による暗号乱数有効期限つき
API キーサービス認証必須暗号乱数機械用パスワード
Saltハッシュ強化不要暗号乱数レインボーテーブル対策
Nonce一回限りの識別不要暗号乱数リプレイ攻撃防止
Signature改ざん検知不要不可逆暗号計算HMAC, RSA 署名

ポイントは、見た目ではなく「設計目的」で分類することです。同じ 32 文字のランダム文字列でも、UUID として使えばただの名札、トークンとして使えば認証の鍵になります。

UUID — 衝突しない名札

UUID(Universally Unique Identifier)は、「世界中で重複しない ID を生成する」ための仕組みです。セキュリティとは直接関係がなく、あくまで識別が目的です。

もっとも広く使われる UUID v4 はランダム生成で、122 ビットのエントロピーを持ちます。これは約 5.3 × 1036 通り ―― 1 秒に 10 億個生成しても、衝突するまで 100 億年以上かかる計算です。

よく使われる場面:

  • データベースの主キー(auto increment の代替)
  • 分散システムでの一意なオブジェクト ID
  • ファイル名の衝突回避(アップロード時など)
  • トラッキング用のリクエスト ID
💡 Tip

UUID v1 はタイムスタンプと MAC アドレスを含むため、生成時刻や端末が推測可能です。外部に公開する ID には v4(完全ランダム)を使いましょう。また、UUID をそのままセッションキーやトークンに流用するのはアンチパターンです。UUID は「ぶつからない」ことは保証しますが、「推測されない」ことは保証しません。

完全無料の UUID 生成ツールを使う

パスワード — 人間が扱う唯一の秘密

パスワードは、この 8 種類の中で唯一「人間が記憶する」ことを前提に設計されています。そのため、エントロピー(ランダム性)は人間の記憶力に依存し、他の文字列と比べて本質的に弱い存在です。

だからこそ、パスワードの保存にはひと手間が必要です。平文で保存するのは論外で、必ずハッシュ化してから保存します。さらに、単純なハッシュではなく、bcryptArgon2scrypt のような「わざと遅い」アルゴリズムを使うのが現代のベストプラクティスです。

なぜ「遅い」ことが重要なのでしょうか? 攻撃者がブルートフォース(総当たり)で 1 秒に数十億回のハッシュ計算を試みるとき、1 回の計算に 0.1 秒かかるアルゴリズムなら、攻撃コストが桁違いに跳ね上がるからです。

よく使われる場面:

  • Web サービスのログイン認証
  • SSH、データベースアクセスの認証
  • 暗号化ファイルの復号鍵(パスフレーズ)
💡 Tip

パスワードの強度は「文字種 × 長さ」で決まります。P@ssw0rd のような「記号を入れただけ」の短いパスワードより、correct horse battery staple のような長いパスフレーズの方が遥かに安全です。パスワードマネージャーの利用を強く推奨します。パスワードマネージャーの利用を強く推奨します。

完全無料のパスワード生成ツールを使う

ハッシュ — デジタル指紋

ハッシュ関数は、任意の長さのデータを固定長の値に変換する一方向関数です。同じ入力からは必ず同じ出力が得られますが、出力から入力を復元することはできません。いわばデータの指紋です。

たとえば、SHA-256 でハッシュすると、「hello」という 5 文字の入力も、1GB のファイルも、どちらも 256 ビット(64 文字の 16 進数)に圧縮されます。元のデータが 1 ビットでも変われば、ハッシュ値はまったく別物になります。

よく使われる場面:

  • パスワード保存 — 平文の代わりにハッシュ値を DB に格納する
  • ファイルの整合性チェック — ダウンロードしたファイルが改ざんされていないか確認する(チェックサム)
  • Git のコミット ID — Git はすべてのコミットを SHA-1 ハッシュで管理している
  • ブロックチェーン — 取引データの連鎖をハッシュで保証する
💡 Tip

MD5 と SHA-1 は衝突攻撃が現実的に可能なため、セキュリティ用途には使わないでください。新規プロジェクトでは SHA-256 以上を選びましょう。パスワード保存には SHA 系ではなく、前述の bcrypt / Argon2 を使います(SHA は「速すぎる」ため、ブルートフォースに弱い)。

完全無料のハッシュ生成ツールを使う

トークン — 有効期限つきの合言葉

トークンは、「この人はログイン済みである」ことを証明する一時的な文字列です。ログインに成功するとサーバーがトークンを発行し、以降のリクエストにはそのトークンを添付して「自分は認証済みです」と主張します。

もっとも有名なのは JWT(JSON Web Token) で、ヘッダー・ペイロード・署名の 3 パートを Base64 エンコードした構造を持ちます。ペイロードにユーザー ID や有効期限が含まれており、署名によって改ざんが検知できます。

よく使われる場面:

  • Web アプリのセッション管理
  • OAuth 2.0 のアクセストークン / リフレッシュトークン
  • メール認証やパスワードリセットのワンタイムリンク
  • SPA(Single Page Application)のステートレス認証
💡 Tip

JWT はペイロードが Base64 エンコード(暗号化ではない)なので、中身は誰でも読めます。パスワードやクレジットカード番号を JWT に入れてはいけません。また、トークンの有効期限は短く設定し(アクセストークンは 15 分〜1 時間が目安)、リフレッシュトークンで再発行するパターンが安全です。

完全無料のトークン生成ツールを使う

API キー — 機械のためのパスワード

API キーは、アプリケーションやサービスが「自分は許可された利用者です」と名乗るための文字列です。人間が入力するのではなく、コードに埋め込んでリクエストに添付します。

パスワードとの最大の違いは、人間が覚える必要がないこと。そのため、十分な長さ(128〜256 ビット)のランダム文字列として生成でき、強度は高くなります。一方で、ソースコードや設定ファイルに平文で書かれがちなので、漏洩リスクが高い側面もあります。

よく使われる場面:

  • 外部 API(Google Maps, OpenAI, Stripe)の利用認証
  • マイクロサービス間の内部通信認証
  • 課金やレート制限の識別
💡 Tip

API キーを GitHub に push してしまう事故は後を絶ちません。.env ファイルや環境変数に格納し、.gitignore に追加するのは基本中の基本です。GitHub 自体にも「Secret Scanning」機能があり、主要サービスの API キーがコミットされると自動で無効化される仕組みがありますが、頼り切りは危険です。

完全無料の API キー・トークン生成ツールを使う

Salt・Nonce・Signature — 裏方の専門家たち

この 3 つは単独で使われることは少なく、他の仕組みを強化するための部品です。

Salt(ソルト)

パスワードをハッシュ化する際に、ユーザーごとに異なるランダム値を付加するのが Salt です。同じパスワード「password123」を使っている 2 人のユーザーがいても、Salt が違えばハッシュ値は異なります。これにより、事前計算されたハッシュ辞書(レインボーテーブル)を使った攻撃を防ぎます。

Salt 自体は秘密にする必要がなく、ハッシュ値と一緒にデータベースに保存します。bcrypt や Argon2 は内部で自動的に Salt を生成・管理してくれるため、開発者が手動で扱う機会は減っています。

Nonce(ナンス)

Nonce は「Number used ONCE」の略で、一度だけ使う使い捨ての値です。主な目的はリプレイ攻撃の防止。通信を盗聴した攻撃者が同じリクエストをもう一度送信しても、Nonce が使用済みなら無効になります。

Web 開発では、CSRF(クロスサイトリクエストフォージェリ)対策のフォームトークンとしても使われます。WordPress の wp_nonce_field() がまさにこれです。

Signature(署名)

Signature は、データが改ざんされていないことを証明します。HMAC(Hash-based Message Authentication Code)では、秘密鍵とメッセージを組み合わせてハッシュを計算します。秘密鍵を知らない第三者は正しい署名を作れないため、受信者は「このデータは正規の送信者から来た」と確認できます。

JWT のヘッダーに含まれる alg: HS256 は「HMAC-SHA256 で署名する」という意味です。API の Webhook(Stripe, GitHub など)でも、リクエストボディの改ざん検知に HMAC 署名が使われています。

設計軸で整理する

8 種類をバラバラに覚えるのではなく、5 つの軸で整理すると頭に入りやすくなります。

種類秘密にする?復元できる?一意性が命?有効期限?人間が使う?
UUID××××
パスワード◎(本人のみ)×
ハッシュ××(不可逆)××
トークン×
API キー××
Salt××××
Nonce×××
Signature××(不可逆)×

注目すべきは、パスワードだけが「人間が使う」に◎がつくこと。パスワードが他のすべてと違う特殊な存在であることが、ここからも見て取れます。

攻撃モデルから考える

セキュリティ設計では「何を守るか」ではなく「どんな攻撃を防ぐか」から考えるのが鉄則です。文字列の種類ごとに、想定される攻撃は異なります。

種類防ぐべき攻撃対策の考え方
UUID衝突(ID の重複)十分なエントロピーで衝突確率を無視できるレベルに
パスワードブルートフォース / 辞書攻撃遅いハッシュ + Salt + 長いパスワード
ハッシュ原像攻撃 / 衝突攻撃安全なアルゴリズム選択(SHA-256 以上)
トークンリプレイ攻撃 / 盗聴短い有効期限 + HTTPS 必須 + リフレッシュ方式
API キー漏洩環境変数管理 + ローテーション + IP 制限
Nonceリプレイ攻撃使い捨て + サーバー側で使用済みチェック
Signature改ざん秘密鍵の厳重管理 + アルゴリズム選択

たとえば、UUID の設計で「ブルートフォース耐性」を考慮する必要はありません。逆に、パスワードの設計で「衝突耐性」を気にする場面はほとんどありません。防ぐべき攻撃が違えば、設計判断も変わります

実務での選び方フロー

「この場面ではどれを使えばいい?」と迷ったときの思考フローです。

  1. 用途を明確にする — 識別? 認証? 検証? 一時的?
  2. 防ぐ攻撃を特定する — 衝突? 推測? 漏洩? リプレイ? 改ざん?
  3. 必要なエントロピーを決める — UUID なら 122 ビット、トークンなら 256 ビット
  4. 生成方法を選ぶMath.random() は NG、crypto モジュールを使う
  5. 保存方法を決める — 平文 OK? ハッシュ化? 暗号化? 環境変数?

特に 4 番目は重要です。プログラミング言語の標準的な乱数生成器(Math.random()random.random())は暗号論的に安全ではありません。セキュリティに関わる文字列の生成には、必ず暗号論的擬似乱数生成器(CSPRNG)を使ってください。Python なら secrets モジュール、Node.js なら crypto.randomBytes() が該当します。

まとめ

8 種類のランダム風文字列を、設計目的で分類すると次の 4 グループになります。

  • 識別:UUID
  • 認証:パスワード、API キー
  • 検証:ハッシュ、Signature
  • 一時認証 / 防御:トークン、Nonce、Salt

見た目が同じでも、設計目的がまったく違う ―― これがこの記事の核心です。

開発者として心がけるべきは、「文字列を見るな、用途を見ろ」という原則です。新しいランダム文字列を設計するときも、既存のものを扱うときも、まず「これは何を守るためのものか?」を問うことで、適切な生成方法・保存方法・有効期限が自然と導き出されます。

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です