Upgrade to Pro — share decks privately, control downloads, hide ads and more …

非公開 URL は安全か?あるいは、そのランダム文字列は本当にランダムなのか?

Avatar for mu_zaru mu_zaru
October 16, 2025

非公開 URL は安全か?あるいは、そのランダム文字列は本当にランダムなのか?

非公開 URL の特徴
- *URL さえ知っていれば*誰でもアクセスできる
- でも URL を*類推することは難しい*(と、されている)
- なので、*認証はなくても限定公開*を実現できている

心配なこと
1. *悪意ある人*がランダム文字列を*予測*できるのでは
2. *たまたま*ランダム文字列を*当てちゃう運良すぎ*な人いるのでは

Avatar for mu_zaru

mu_zaru

October 16, 2025
Tweet

More Decks by mu_zaru

Other Decks in Programming

Transcript

  1. 非公開 URL の特徴 URL さえ知っていれば誰でもアクセスできる でも URL を類推することは難しい (と、 されている)

    なので、 認証はなくても限定公開を実現できている 完全ではないが、 現実的に要件は満たしているのでOKというシーンで使われる
  2. 固定周期から払い出すのを再現するとこんな感じ function PRNG(sequence) { let count = 0; return function

    rand() { return sequence[count++ % sequence.length]; }; } const rand = PRNG([3, 1, 4, 1, 5]); rand(); // 3 rand(); // 1 rand(); // 4
  3. PHP で 1 から 100 までのランダム数値を出力 <?php echo rand(1, 100);

    // 実行するたびにランダム数値が出力される // 78 // 25 // 92 ちゃんとランダムになっているっぽいが
  4. srand() でシードを指定 <?php srand(1); // シードを1に固定 echo rand(1, 100); //

    46 何回実行しても必ず 46 がでる // 46 入力 (シード) が同じなら結果も常に同じ 要は、 マイクラのシード。 同じシードをいれると同じ世界が生成される
  5. Math.random() の結果を 4 つほど収集 Array.from({ length: 4 }, Math.random); //

    [ // 0.008320063101796449, // 0.9745605653695509, // 0.29882177297695456, // 0.2735565840354114, // ]
  6. 結果を予測スクリプトに渡す js-randomness-predictor \ --environment chrome \ --sequence \ 0.008320063101796449 \

    # ←生成した乱数 0.9745605653695509 \ 0.29882177297695456 \ 0.2735565840354114
  7. 可逆的というのは x + 10 = 15 という式があった時、 計算ロジックと解が分か れば、 一意の

    x を求めることができる、 ということ Math.random のアルゴリズムは JS エンジンによって異なるが、 Chrome の V8 では xorsh ift128+ が使われていて、 可逆的アルゴリズムである
  8. 今回の Math.random で使われている XorShift128+ は線形で可逆 的。 総当たりで入力値を計算するのは非現実的だが、 精度が落ちた出 力であっても計算範囲を狭められるので、 現実的に割り出すことがで

    きる Math.random の本来の出力結果は 53 ビットだが、 14 ビット程度に 丸められてても、 ノート PC で数分で入力値が出る。 スパコンなどだ と、 もっと精度が落ちてても計算できる (かも) 精度が落ちても計算可能 (時間はかかる)
  9. 暗号学的 擬似乱数生成器の例 import { randomBytes } from "node:crypto"; export function

    randomToken() { return randomBytes(32).toString("base64url"); } crypto.randomUUID();
  10. 例えば NU95SEV0flhvHVeypk4YD2Sqq3aT0Os8RTt0qomzW9M これは BASE64 エンコードで 43 文字種、 64 文字あるので、 文字種の

    組み合わせだけなら 64^43 で、2^258 の大きさ。 これは 「不可思議」 よりも遥かに大きい。 世界最高峰スパコンで総当り しても、 宇宙が誕生してから現在までの時間を 47 回繰り返しても、 ま だ全く足りない。 そして、 年末ジャンボ 1 等が 「11 年連続」 で毎年当たるくらい。