JavaScriptで暗号学的に安全な乱数を生成するために、Web Crypto APIの`crypto.getRandomValues()`メソッドが広く使われています。このメソッドは、予測不可能な高品質な乱数を生成できるため、セキュリティが重要なアプリケーションで特に重宝されます。

crypto.getRandomValues()の基本的な使い方

// TypedArrayを準備
const array = new Uint8Array(16);

// 乱数を生成
crypto.getRandomValues(array);

console.log(array);

メソッドの特徴

1. 暗号学的に安全な乱数生成

2. 予測不可能性が高い

3. ブラウザの標準APIとして実装

4. 高いパフォーマンス

サポートされている配列型

  • Uint8Array
  • Uint16Array
  • Uint32Array
  • Int8Array
  • Int16Array
  • Int32Array
  • BigUint64Array
  • BigInt64Array

実践的な使用例

パスワード生成

function generateRandomPassword(length = 12) {
    const charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    const array = new Uint8Array(length);
    crypto.getRandomValues(array);
    
    return Array.from(array)
        .map(x => charset[x % charset.length])
        .join('');
}

console.log(generateRandomPassword()); // ランダムなパスワードを出力

ランダムなトークン生成

function generateToken() {
    const array = new Uint8Array(16);
    crypto.getRandomValues(array);
    return Array.from(array)
        .map(b => b.toString(16).padStart(2, '0'))
        .join('');
}

console.log(generateToken()); // 16バイトのランダムなトークンを16進数で出力

エラー対処法

一般的なエラーと解決策

1. TypeError: crypto.getRandomValues is not a function

- 原因:cryptoオブジェクトが見つからない

- 解決策:window.cryptoを使用する

```javascript

const crypto = window.crypto || window.msCrypto;

```

2. QuotaExceededError

- 原因:65,536バイトを超える配列サイズ

- 解決策:より小さな配列サイズを使用する

ベストプラクティス

1. エラーハンドリングを適切に実装

try {
    crypto.getRandomValues(array);
} catch (err) {
    console.error('暗号化乱数生成に失敗しました:', err);
}

2. ブラウザ互換性の確認

if (window.crypto && window.crypto.getRandomValues) {
    // crypto.getRandomValues()を使用
} else {
    // フォールバック処理
}

セキュリティ上の注意点

1. Math.random()との違い

- Math.random()は暗号学的に安全ではない

- 重要なセキュリティ機能には必ずcrypto.getRandomValues()を使用

2. 用途に応じた適切な実装

- パスワード生成

- セッションID

- 暗号化キー

- 認証トークン

まとめ

crypto.getRandomValues()は、JavaScriptで暗号学的に安全な乱数を生成するための標準的な方法です。適切に実装することで、セキュアなアプリケーション開発が可能になります。ブラウザの互換性やエラーハンドリングに注意を払い、用途に応じて適切に使用することが重要です。